大家好,欢迎来到IT知识分享网。
之前一片文章,学习了ActivityThread是App的真正入口,他在内部维护了一个ApplicationThread对象,他和远程的ams进行通信。当创建Activity时,调用ams通过Binder机制调用ApplicationThread对象的方法,进而调用ActivityThread中的handleResumeActivity方法,最终调用Activity中的onResume()方法。
在以前的印象中onResume()这个生命周期表示当前的Activity对用户可见,这是不是表示onResume()之前页面就已经绘制出来了呢?Activity的UI实在什么时候开始绘制的呢?带着这些疑问来研究研究。。。
/**
* <p>Keep in mind that onResume is not the best indicator that your activity
* is visible to the user; a system window such as the keyguard may be in
* front. Use {@link #onWindowFocusChanged} to know for certain that your
* activity is visible to the user (for example, to resume a game).
* 只有当onWindowFocusChanged方法被调用的时候,才能确认当前的Activity对用户的可见的
*/
@CallSuper
protected void onResume() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
getApplication().dispatchActivityResumed(this);
mActivityTransitionState.onResume();
mCalled = true;
}
我去,颠覆三观,一直以为onResume的时候,Activity就对用户可见了。
为了研究这个问题,还得回到ActivityThread类里面来分析,看看handleResumeActivity方法
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
...
// 调用Activity的performResume()方法,即onResume()方法
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
} else if (!willBeVisible) {
if (localLOGV) Slog.v(
TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r);
// The window is now visible if it has been added, we are not
// simply finishing, and we are not starting another activity.
//window这个时候已经是可见的
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
...
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);//更新视图
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();//调用Activity的makeVisible()方法
}
}
...
} else {
// If an exception was thrown when trying to resume, then
// just end this activity.
try {
ActivityManagerNative.getDefault()
.finishActivity(token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
}
}
}
在这个方法中,做了三件事:
- 调用performResumeActivity方法,这个方法会调用Activity的performResume()方法,即onResume()方法
- 绘制UI
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
view decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);//更新视图
}
- 调用Activity的makeVisible()方法
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);//这个时候Activity设置的视图才真正对用户可见
}
从上面的分析来看,Activity的生命周期方法onResume()的调用,并不会意味着View已经对用户可见,只是表示系统将立刻绘制Activity设置的视图。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/22795.html