Activity 源码详解之创建

相信大家对于 Activity 的生命周期都不陌生吧,但是你真的知道 Activity 的生命周期是在什么时候调用的吗?我当时研究的时候,确实走了弯路了,最后发现如何把生命周期和存取数据的方法联系起来解读,会很方便。如果你们想看原文,就去这里找吧。但是我不会像他那样,上去直接抛出 ViewManager、WindowManager 和 WindowManagerImpl。

一、启动 Activity

开始正文,直接来看我们的 ActivityThread.handleLaunchActivity 去查看 Activity 的创建:

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

            if (!r.activity.mFinished && r.startsNotResumed) {
                //调用 onPause
                performPauseActivityIfNeeded(r, reason);
                ...
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

重要的代码全在这里了,来看下第 3 行,咱们去看下这个方法的源码,看看它具体返回了什么:

    public static void initialize() {
        getWindowManagerService();
    }

    public static IWindowManager getWindowManagerService() {
        synchronized (WindowManagerGlobal.class) {
            if (sWindowManagerService == null) {
                sWindowManagerService = IWindowManager.Stub.asInterface(
                        ServiceManager.getService("window"));
                try {
                    if (sWindowManagerService != null) {
                        ValueAnimator.setDurationScale(
                                sWindowManagerService.getCurrentAnimatorScale());
                    }
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowManagerService;
        }
    }

应该说通过 WindowManagerGlobal.initialize(); 得到了是一个 WindowManagerService,那么它是什么呢?这就要说到 IPC 机制了,但是这里我不想深入讲解,如果需要的话,可以看下我之前抄的主席的《开发艺术探索》中的内容,就明白咋回事了,这里我只能解释 ActivityManagerNative 与 ActivityManagerProxy 相当于一个 Binder 的客户端,而 ActivityManagerService 相当于 Binder 的服务端。

到这里我们知道通过 WindowManagerGlobal.initialize(); 得到了是一个 WindowManagerService,至于具体有什么用,说实话,它在这篇文章中还这没有什么用。好,继续走,在 handleLaunchActivity 方法的第 5 行调用了一个重要的方法 performLaunchActivity:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            ActivityInfo aInfo = r.activityInfo;
            if (r.packageInfo == null) {
                r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                        Context.CONTEXT_INCLUDE_CODE);
            }
            // 解析 intent 中的数据
            ComponentName component = r.intent.getComponent();
            if (component == null) {
                component = r.intent.resolveActivity(
                    mInitialApplication.getPackageManager());
                r.intent.setComponent(component);
            }
        
            if (r.activityInfo.targetActivity != null) {
                component = new ComponentName(r.activityInfo.packageName,
                        r.activityInfo.targetActivity);
            }
        
            ContextImpl appContext = createBaseContextForActivity(r);
            Activity activity = null;
            try {
                // 用ClassLoader(类加载器)将目标activity的类通过类名加载进来并调用newInstance来实例化一个对象
                // 其实就是通过Activity的无参构造方法来new一个对象,对象就是在这里new出来的。
                java.lang.ClassLoader cl = appContext.getClassLoader();
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                ...
            }
            ...
            try {
                // 创建 Application
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                ...
                if (activity != null) {
                    ...
                    // attach 被调用,Window 也是这个时候被初始化的
                    activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.configCallback);
        
                    ...
                    // theme 设置
                    int theme = r.activityInfo.getThemeResource();
                    if (theme != 0) {
                        activity.setTheme(theme);
                    }
                    // 调用 Activity 的 onCreate 生命周期
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onCreate()");
                    }
                    r.activity = activity;
                    r.stopped = true;
                    // 调用 Activity 的 onStart 生命周期
                    if (!r.activity.mFinished) {
                        activity.performStart();
                        r.stopped = false;
                    }
                    if (!r.activity.mFinished) {
                        if (r.isPersistable()) {
                            if (r.state != null || r.persistentState != null) {
                                // 调用 Activity 的 OnRestoreInstanceState 恢复数据
                                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                        r.persistentState);
                            }
                        } else if (r.state != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                        }
                    }
                    ...
                }
            ...
            } 
            return activity;
        }

代码有点多,我们分块解读下,创建 Activity 对象就不说了,我们来看下 attach 这个方法,这也是在 onCreate 之前调用的 唯一一个方法,用过 fragment 的都知道,一般在 fragment 中最好使用 attach 来获取 Context,而不是直接使用 getActivity 方法,为什么在 fragment 中 调用 attach 赋值 Context 后,在 onCreateView 中使用不会报错,原因就在此。一起来看下这个方法做了什么:

    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        attachBaseContext(context);
    
        mFragments.attachHost(null /*parent*/);
        // Window 创建
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        ...
        // Window 绑定 WindowManager
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    
        mWindow.setColorMode(info.colorMode);
    }

怎么样,我没有骗你们吧,Window 的创建就是在 attach 中创建的,不仅如此,我们还发现在 attach 中,还创建了 WindowManager,并且把 Window 和 WindowManager 绑定了。

好了,到这里我们该分析的都分析完了,接下来就是我们最最最常用的 Activity 生命周期了。

1. onCreate 生命周期

我们继续看 performLaunchActivity 方法,来看下第 54 行,不要问我为什么不是第 52 行,其实都一样:

    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

来看下 Activity 的 performCreate 方法:

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        mActivityTransitionState.readState(icicle);

        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchActivityCreated();
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    }

请大声告诉我你看到了什么,没错,就是我们熟悉的 onCreate,

2. onStart 生命周期

我们继续看 performLaunchActivity 方法的第 65 行,这个有点难找了,我们还是先来看下这个方法吧:

    final void performStart() {
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
        mFragments.noteStateNotSaved();
        mCalled = false;
        mFragments.execPendingActions();
        // 看这里
        mInstrumentation.callActivityOnStart(this);
        ...
    }

我们发现调用了 Instrumentation 的 callActivityOnStart 方法,我们跟着源码继续往下走:

  public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }

看到了吧,在这里调用的 onStart 方法。

3. onRestoreInstanceState 恢复数据

我们继续看 performLaunchActivity 的第 72、73 行,调用了 callActivityOnRestoreInstanceState,好吧,我们继续看源码:

    public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState,
            PersistableBundle persistentState) {
        activity.performRestoreInstanceState(savedInstanceState, persistentState);
    }

    final void performRestoreInstanceState(Bundle savedInstanceState) {
        onRestoreInstanceState(savedInstanceState);
        restoreManagedDialogs(savedInstanceState);
    }

到这里,不用我解释了吧,Bundle 还有不会用的吗?老铁,你还是自己百度吧,恕小弟不能奉陪你了。

到这里,performLaunchActivity 方法已经分析完了,在这个里边,我们知道它通过 attach 创建了Context,还创建了 Window 和 WindowManager,并且把两者进行了绑定,然后调用了 Activity 的 onCreate 和 onStart 生命周期,还调用了我们用来恢复数据的 onRestoreInstanceState 方法。

4. onResume 生命周期

我们再来看下 handleLaunchActivity 方法:

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

            if (!r.activity.mFinished && r.startsNotResumed) {
                //调用 onPause
                performPauseActivityIfNeeded(r, reason);
                ...
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

这次我们看第 11 行的 handleResumeActivity 方法:

    final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        ...
        // TODO Push resumeArgs into the activity for consideration
        // 调用 Activity 的 onResume 生命周期
        r = performResumeActivity(token, clearHide, reason);

        if (r != null) {
            ...
            // mStartedActivity 如果不适用 startActivityForResult,则为 false,
   // startActivity 调用的契税是 startActivityForResult(intent,-1),只有当 requestCode 大于 0, mStartedActivity 为 true
            boolean willBeVisible = !a.mStartedActivity;
            ...
            r.window一开始activity并未赋值给ActivityClientRecord,所以这里为null
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                // 设置 DecorView 为 INVISIBLE
                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 (r.mPreserveWindow) {
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                    // Normally the ViewRoot sets up callbacks with the Activity
                    // in addView->ViewRootImpl#setView. If we are instead reusing
                    // the decor view we have to notify the view root that the
                    // callbacks may have changed.
                    ViewRootImpl impl = decor.getViewRootImpl();
                    if (impl != null) {
                        impl.notifyChildRebuilt();
                    }
                }
                if (a.mVisibleFromClient) {
                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
                        // 将 DecorView 和 WindowManager 绑定
                        wm.addView(decor, l);
                    } else {
                        // The activity will get a callback for this {@link LayoutParams} change
                        // earlier. However, at that time the decor will not be set (this is set
                        // in this method), so no action will be taken. This call ensures the
                        // callback occurs with the decor set.
                        a.onWindowAttributesChanged(l);
                    }
                }
            ...
            if (!r.activity.mFinished && willBeVisible
                    && r.activity.mDecor != null && !r.hideForNow) {
                // 标记当前的Activity有没有设置新的配置参数
                // 比如现在手机是横屏的,而之后你转成竖屏,那么这里的 newCofig 就会被赋值,表示参数改变
                if (r.newConfig != null) {
                    // 回调  如果发生改变
                    performConfigurationChangedForActivity(r, r.newConfig);
                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                            + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
                    r.newConfig = null;
                }
                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                        + isForward);
                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();
                        // 更新 DecorView
                        wm.updateViewLayout(decor, l);
                    }
                }

                r.activity.mVisibleFromServer = true;
                mNumVisibleActivities++;
                if (r.activity.mVisibleFromClient) {
                    // DecorView 显示
                    r.activity.makeVisible();
                }
            }
            ...
            if (reallyResume) {
                try {
                    // 通知 ActivityManagerService,Activity 完成 onResume
                    ActivityManager.getService().activityResumed(token);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }

        } else {
            // If an exception was thrown when trying to resume, then
            // just end this activity.
            try {
                ActivityManager.getService()
                    .finishActivity(token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

好吧,我承认代码也贼多咧啊,我把注释加完就后悔了,还不如让你们直接往下看呢,要这么看,非累死不可,

我们把它拆分开来,先看 3 - 7 行代码,

        ActivityClientRecord r = mActivities.get(token);
        ...
        // TODO Push resumeArgs into the activity for consideration
        // 调用 Activity 的 onResume 生命周期
        r = performResumeActivity(token, clearHide, reason);

我们来看下 performResumeActivity 方法:

    public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
                + " finished=" + r.activity.mFinished);
        if (r != null && !r.activity.mFinished) {
            if (clearHide) {
                r.hideForNow = false;
                r.activity.mStartedActivity = false;
            }
            try {
                r.activity.onStateNotSaved();
                r.activity.mFragments.noteStateNotSaved();
                checkAndBlockForNetworkAccess();
                if (r.pendingIntents != null) {
                    deliverNewIntents(r, r.pendingIntents);
                    r.pendingIntents = null;
                }
                if (r.pendingResults != null) {
                    deliverResults(r, r.pendingResults);
                    r.pendingResults = null;
                }
                // 在这里
                r.activity.performResume();

                synchronized (mResourcesManager) {
                    // If there is a pending local relaunch that was requested when the activity was
                    // paused, it will put the activity into paused state when it finally happens.
                    // Since the activity resumed before being relaunched, we don't want that to
                    // happen, so we need to clear the request to relaunch paused.
                    for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
                        final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
                        if (relaunching.token == r.token
                                && relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
                            relaunching.startsNotResumed = false;
                        }
                    }
                }

                EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
                        r.activity.getComponentName().getClassName(), reason);

                r.paused = false;
                r.stopped = false;
                r.state = null;
                r.persistentState = null;
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                        "Unable to resume activity "
                        + r.intent.getComponent().toShortString()
                        + ": " + e.toString(), e);
                }
            }
        }
        return r;
    }

其实 performResumeActivity 不仅调用了 onResume 生命周期,同时还把 Activity 的信息记录在 ActivityClientRecord。好吧,看来我们还是需要回到 Activity 来查看 performResume 方法:

    final void performResume() {
        // 调用 Activity 的 onRestart
        performRestart();
        mFragments.execPendingActions();
        // 调用 Activity 的 onResume 生命周期
        mInstrumentation.callActivityOnResume(this);
    }

你们应该发现了,在这里同时调用了 performRestart 方法,这时候或许有人就迷惑了,卧槽,看着源码逻辑,在调用 onResume 之前应该是先调用 onRestart 啊,但是和老师讲的或者自学的结果不一样啊。不,其实你没错,我们来看看 performRestart 怎么做的:

    final void performRestart() {
        ...
        if (mStopped) {
            mStopped = false;
            ...
            mCalled = false;
            mInstrumentation.callActivityOnRestart(this);
            ...
        }
    }

Google 已经做好了判断的,所以不要不相信你学到的,至于 mInstrumentation.callActivityOnResume(this); 和  mInstrumentation.callActivityOnRestart(this); 我这里就不贴源码了,自己看下吧,原理和 onStart 是一样的。

我们继续拆分 handleResumeActivity 方法,这次看 16 - 50 行:

    if (r.window == null && !a.mFinished && willBeVisible) {
        r.window = r.activity.getWindow();
        View decor = r.window.getDecorView();
        // 设置 DecorView 为 INVISIBLE
        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 (r.mPreserveWindow) {
            a.mWindowAdded = true;
            r.mPreserveWindow = false;
            // Normally the ViewRoot sets up callbacks with the Activity
            // in addView->ViewRootImpl#setView. If we are instead reusing
            // the decor view we have to notify the view root that the
            // callbacks may have changed.
            ViewRootImpl impl = decor.getViewRootImpl();
            if (impl != null) {
                impl.notifyChildRebuilt();
            }
        }
        if (a.mVisibleFromClient) {
            if (!a.mWindowAdded) {
                a.mWindowAdded = true;
                // 将 DecorView 和 WindowManager 绑定
                wm.addView(decor, l);
            } else {
                // The activity will get a callback for this {@link LayoutParams} change
                // earlier. However, at that time the decor will not be set (this is set
                // in this method), so no action will be taken. This call ensures the
                // callback occurs with the decor set.
                a.onWindowAttributesChanged(l);
            }
        }

其实这里呢,理解起来也很简单了,就是获取 Activity 的 Window,然后通过 Window 获取 DecorView,再通过 getWindowManager 获取 WindowManager,前面我们已经看到过这样的代码了在 Activity 的 attach 方法中。然后设置 DecorView 为不可见状态,并且将 DecorView 和 WindowManager 绑定在一起。

下面思考一个问题,这个 DecorView 是 setContentView 绑定布局以前的吗?

接下来,我们来看下 handleResumeActivity 方法的 52 -78 行:

    if (!r.activity.mFinished && willBeVisible
            && r.activity.mDecor != null && !r.hideForNow) {
        // 标记当前的Activity有没有设置新的配置参数
        // 比如现在手机是横屏的,而之后你转成竖屏,那么这里的 newCofig 就会被赋值,表示参数改变
        if (r.newConfig != null) {
            // 回调  如果发生改变
            performConfigurationChangedForActivity(r, r.newConfig);
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                    + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
            r.newConfig = null;
        }
        if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                + isForward);
        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();
                // 更新 DecorView
                wm.updateViewLayout(decor, l);
            }
        }

这里应该不需要讲太多了,横竖屏切换我们都知道了,来看下这个回调吧,它会调用 performConfigurationChangedForActivity 方法,那我们就来看下这个方法:

    private void performConfigurationChangedForActivity(ActivityClientRecord r,
            Configuration newBaseConfig) {
        performConfigurationChangedForActivity(r, newBaseConfig,
                r.activity.getDisplay().getDisplayId(), false /* movedToDifferentDisplay */);
    }

    private Configuration performConfigurationChangedForActivity(ActivityClientRecord r,
            Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) {
        r.tmpConfig.setTo(newBaseConfig);
        if (r.overrideConfig != null) {
            r.tmpConfig.updateFrom(r.overrideConfig);
        }
        final Configuration reportedConfig = performActivityConfigurationChanged(r.activity,
                r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay);
        freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
        return reportedConfig;
    }

    private Configuration performActivityConfigurationChanged(Activity activity,
            Configuration newConfig, Configuration amOverrideConfig, int displayId,
            boolean movedToDifferentDisplay) {
        ...
        if (shouldChangeConfig) {
            activity.mCalled = false;
            activity.onConfigurationChanged(configToReport);
            if (!activity.mCalled) {
                throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
                                " did not call through to super.onConfigurationChanged()");
            }
        }

        return configToReport;
    }

我们发现最终调用了 Activity 的 onConfigurationChanged,那我们继续来看下 onConfigurationChanged 是在那里写的:

    public void onConfigurationChanged(Configuration newConfig) {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onConfigurationChanged " + this + ": " + newConfig);
        mCalled = true;

        mFragments.dispatchConfigurationChanged(newConfig);

        if (mWindow != null) {
            // Pass the configuration changed event to the window
            mWindow.onConfigurationChanged(newConfig);
        }

        if (mActionBar != null) {
            // Do this last; the action bar will need to access
            // view changes from above.
            mActionBar.onConfigurationChanged(newConfig);
        }
    }

我用的是 26 的 SDK,源码可能不相同,emmmmm,屏幕横竖屏切换会回调的方法我们已经找到了。那接下来就看你们的了。

好了,我们继续往下看 handleResumeActivity 方法的 82 - 85 行代码:

    if (r.activity.mVisibleFromClient) {
        // DecorView 显示
        r.activity.makeVisible();
    }

我们来看下 makeVisible 方法:

    void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }

还记得我们之前把 DecorView 设置为不可见了吧,现在这这里才让它显示出来的。反正我不知道为什么要这么设计,有知道的可以说下,难道是为了不让我们看到它绘制界面的动画吗(手动滑稽),嘿嘿!!

到这里,Activity 被启动起来,视图(DecorView)也被创建(Window)管理(WindowManager)起来了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值