ActivityThread读书笔记2-onResume的调用时机

来源:互联网 发布:lols7总决赛武汉知乎 编辑:程序博客网 时间:2024/06/16 13:21

之前一片文章,学习了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对用户的可见的 */@CallSuperprotected 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设置的视图。

0 0
原创粉丝点击