【Android】Activity 生命周期解析

之前的笔记【Android】Framework笔记——Activity 启动流程简述Activity 的启动流程进行了一次分析,里面简单提到了 ActivityonCreateonResume 是如何调用的,今天就让我们正式以 Activity 的生命周期的角度,对 Activity 的源码进行进一步的分析。

Activity 创建

首先我们看到 handleLaunchActivity 方法,它对 Activity 进行了创建并最终导致了 onCreate 的调用。

@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    // ...
    // 初始化 WindowManagerGlobal
    WindowManagerGlobal.initialize();
    // 启动 Activity
    final Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        // ...
        // 对 onRestoreInstanceState 的 state 进行设置
        if (!r.activity.mFinished && pendingActions != null) {
            pendingActions.setOldState(r.state);
            pendingActions.setRestoreInstanceState(true);
            pendingActions.setCallOnPostCreate(true);
        }
    } 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();
        }
    }
    return a;
}

这里调用到了 performLaunchActivity,并且启动成功后对 onRestoreInstanceState 的 state 进行了设置,从而恢复状态。

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);
        }
        // 获取之前 PMS 解析的 ComponentName
        ComponentName component = r.intent.getComponent();
        // 创建 Activity 的 ContextImpl
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            // 通过反射构造 Activity 并初始化
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }
        try {
                // 构造 Application(如果已经创造内部直接获取当前的 Application)
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            // ...
            if (activity != null) {
                // ...
                appContext.setOuterContext(activity);
                // attach
                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);
                // ...
                // 调用 onCreate
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                // ...
                r.activity = activity;
            }
            r.setState(ON_CREATE);
            mActivities.put(r.token, r);
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }
        return activity;
    }

这里步骤如下:

  1. 通过 mInstrumentation.newActivity 构造一个 Activity 对象。
  2. 获取 Application 并调用 activity.attach
  3. 通过 mInstrumentation.callActivityOnCreate 调用 Activity.performCreate 方法。

通过 mInstrumentation.newActivity 创建了 Activity

public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    String pkg = intent != null && intent.getComponent() != null
            ? intent.getComponent().getPackageName() : null;
    return getFactory(pkg).instantiateActivity(cl, className, intent);
}

这里获取到的 Factory 实际上是 AppComponentFactory,其 instantiateActivity 会在内部通过传入的 ClassLoader 加载类并通过反射构建 Activity 对象。

Activity 初始化

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) {
    // attachContext
    attachBaseContext(context);

    mFragments.attachHost(null /*parent*/);
        // 创建 PhoneWindow 并初始化属性
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowControllerCallback(this);
    // ...
    // 设置 Activity 的属性
    mUiThread = Thread.currentThread();
        // ...
    mApplication = application;
    // ...
    // 对 PhoneWindow 设置 WindowMananger
    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);
}

attach Context

由于 Activity 只是一个 ContextWrapper,它只是个包装类。因此需要将 ContextImpl 通过 attachBaseContext 设置进来。

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    newBase.setAutofillClient(this);
}

PhoneWindow 创建

public PhoneWindow(Context context, Window preservedWindow,
        ActivityConfigCallback activityConfigCallback) {
    this(context);
    // Only main activity windows use decor context, all the other windows depend on whatever
    // context that was given to them.
    mUseDecorContext = true;
    if (preservedWindow != null) {
        mDecor = (DecorView) preservedWindow.getDecorView();
        mElevation = preservedWindow.getElevation();
        mLoadElevation = false;
        mForceDecorInstall = true;
        // If we're preserving window, carry over the app token from the preserved
        // window, as we'll be skipping the addView in handleResumeActivity(), and
        // the token will not be updated as for a new window.
        getAttributes().token = preservedWindow.getAttributes().token;
    }
    // Even though the device doesn't support picture-in-picture mode,
    // an user can force using it through developer options.
    boolean forceResizable = Settings.Global.getInt(context.getContentResolver(),
            DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
    mSupportsPictureInPicture = forceResizable || context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_PICTURE_IN_PICTURE);
    mActivityConfigCallback = activityConfigCallback;
}

PhoneWindow 创建时,会对 DecorView 进行创建。DecorViewFrameLayout 的子类,它内部往往是如下的形式:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:fitsSystemWindows="true">
    <ViewStub android:id="@+id/action_mode_bar_stub"
              android:inflatedId="@+id/action_mode_bar"
              android:layout="@layout/action_mode_bar"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:theme="?attr/actionBarTheme" />
    <FrameLayout
        android:layout_width="match_parent" 
        android:layout_height="?android:attr/windowTitleSize"
        style="?android:attr/windowTitleBackgroundStyle">
        <TextView android:id="@android:id/title" 
            style="?android:attr/windowTitleStyle"
            android:background="@null"
            android:fadingEdge="horizontal"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>
    <FrameLayout android:id="@android:id/content"
        android:layout_width="match_parent" 
        android:layout_height="0dip"
        android:layout_weight="1"
        android:foregroundGravity="fill_horizontal|top"
        android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>

其中 content 部分就是我们应用能够绘制的区域了,也就是 setContentView 设置布局文件的区域。

onCreate

mInstrumentation.callActivityOnCreate 中会调用到 Activity.performCreate 方法:

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());
}

performCreate 中就会调用到对应的 onCreate 方法。在 onCreate 中我们往往会调用到 setContentView,它会递归对 XML 进行解析并构建 View 对象。具体过程可以看到我之前写的另一篇文章:【Android】Framework笔记——setContentView流程

onStart

通过 ActivityThread.handleStartActivity ,最终会导致 onStart 的调用。

@Override
public void handleStartActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions) {
    final Activity activity = r.activity;
    // 调用 Activity.peformStart
    activity.performStart("handleStartActivity");
    r.setState(ON_START);
    if (pendingActions == null) {
        // No more work to do.
        return;
    }
    // 如果有保存的状态,调用 onRestoreInstanceState
    if (pendingActions.shouldRestoreInstanceState()) {
        if (r.isPersistable()) {
            if (r.state != null || r.persistentState != null) {
                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                        r.persistentState);
            }
        } else if (r.state != null) {
            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
        }
    }
    // ...
}

可以看到,这里首先通过 Activity.performStart 最终调用了 onStart,之后如果有保存的状态则会调用 onRestoreInstanceState 方法。

final void performStart() {
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    mFragments.noteStateNotSaved();
    mCalled = false;
    mFragments.execPendingActions();
    // 调用 Instrumentation 的 callActivityStart 方法
    mInstrumentation.callActivityOnStart(this);
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onStart()");
    }
    // ...
}

peformStart 中,同样是通过 mInstrumentation.callActivityOnStart 通过 Instrumentation 来调用 onStart 方法。

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

这里直接调用到了 Activity.onStart,此时往往 Activity 已经可视,只是还没有出现在前台。

onRestoreInstanceState

前面的 handleStartActivity 中,如果 Activity 存在之前的 state,则会调用到 mInstrumentation.callActivityOnRestoreInstanceState 方法:

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

它会调用到 activity.performRestoreInstanceState 方法:

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

最终导致 onRestoreInstanceState 被调用,用户就可以在这里对之前保存的状态进行恢复了。

onResume

onResume 往往由 handleResumeActivity 开始,最终导致 onResume 的调用。

@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
        String reason) {
    // 调用 performResumeActivity
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
    // ...
    final Activity a = r.activity;
    // ...
    if (r.window == null && !a.mFinished && willBeVisible) {
            // DecorView 的获取
        r.window = r.activity.getWindow();
        View decor = r.window.getDecorView();
        decor.setVisibility(View.INVISIBLE);
        // 通过 Activity 获取 WindowMananger
        ViewManager wm = a.getWindowManager();
        WindowManager.LayoutParams l = r.window.getAttributes();
        a.mDecor = decor;
        if (a.mVisibleFromClient) {
            if (!a.mWindowAdded) {
                a.mWindowAdded = true;
                // 如果还未 addWindow,通过 WindowManager 进行 addWindow
                wm.addView(decor, l);
            } else {
                // ...
            }
        }
    }
    // ...
    Looper.myQueue().addIdleHandler(new Idler());
}

可以看到,这里首先调用了 performResumeActivity。之后若 ActivityClientRecordPhoneWindow 还没有被添加到 WindowManager,则会通过 wm.addView 方法将 DecorView 添加到 wm 中,这就是 Android 中绘制的起点。

首先我们看看 onResume 的调用流程,看到 performResumeActivity 的实现:

public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
        String reason) {
    final ActivityClientRecord r = mActivities.get(token);
    // ...
    try {
        // ...
        r.activity.performResume(r.startsNotResumed, reason);
        r.state = null;
        r.persistentState = null;
        r.setState(ON_RESUME);
    } 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;
}

它最终调用到了 Activity.performResume 方法:

final void performResume() {
    performRestart();
    // ...
    mInstrumentation.callActivityOnResume(this);
    // ...
}

这里会首先调用到 performRestart 方法,之后会调用 mInstrumentation.callActivityOnResume 方法。

public void callActivityOnResume(Activity activity) {
    activity.mResumed = true;
    activity.onResume();

    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                am.match(activity, activity, activity.getIntent());
            }
        }
    }
}

它最终会调用到 onResume 方法,这里就意味着 Activity 已处于前台,往往从其他页面回来(也就是恢复)的时候会回调该方法。

绘制

onResume 调用完成后,若 ActivityPhoneWindow 还没有通过 WindowManager 添加,会通过 wm.addViewDecorView 添加到 WindowManager,这就是绘制的开始。

其中 WindowManager 实际上只是个接口,它的实现类是 WindowManagerImpl,但它也仅仅是一个 WindowManagerGlobal 这个单例类的代理,因此我们看到 WindowManagerGlobal.addView

public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow) {
    // ...
    ViewRootImpl root;
    View panelParentView = null;

    synchronized (mLock) {
        // 创建 ViewRootImpl
        root = new ViewRootImpl(view.getContext(), display);

        view.setLayoutParams(wparams);
                // 添加 View 和 ViewRootImpl 到对应集合中
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);

        try {
                // 开始绘制
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
            // BadTokenException or InvalidDisplayException, clean up.
            if (index >= 0) {
                removeViewLocked(index, true);
            }
            throw e;
        }
    }
}

这里首先构建了一个 ViewRootImpl,它实际上不是真正的 View,只是一个虚拟的 View 的根,它往往对应了一个 View,也就是传递进来的 DecorView

WindowManagerGlobal 中维护了一个 ViewViewRootImplArrayList,这个 ArrayList 就表示了它们的映射关系。

绘制的起点就是这个 View 的『根』ViewRootImpl当调用 ViewRootImpl.setView 时,就会触发对当前调用线程的检查以及界面的绘制

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    synchronized (this) {
        if (mView == null) {
            // ...
            mView = view;
            // 调用 requestLayout
            requestLayout();
            // ...
        }
    }
}

这里的 requestLayout 方法会触发界面的刷新,从而导致界面的绘制:

@Override
public void requestLayout() {
    if (!mHandlingLayoutInLayoutRequest) {
            // 检查当前线程
        checkThread();
        mLayoutRequested = true;
        // 进行绘制
        scheduleTraversals();
    }
}

这里的 checkThread 会对当前执行的线程进行检查,确保在 UI 线程执行,之后会通过 scheduleTraversals 进行绘制。

我们可以看到 checkThread 方法:

void checkThread() {
    if (mThread != Thread.currentThread()) {
        throw new CalledFromWrongThreadException(
                "Only the original thread that created a view hierarchy can touch its views.");
    }
}

它会在当前线程不是 UI 线程时抛出我们常见的不能在子线程进行 UI 操作的异常。这也就是为什么我们在子线程更新 UI 会抛出异常的原因。

同时,我们也知道,在某些情况下仍能更新 UI,这其实也是这个方法没有调用的原因。(例如在 onCreate 中立马开个子线程更新 UI,此时由于 ViewRootImpl 还没来得及创建,就可以更新 UI)。

关于绘制的更详细的部分,可以看看我的博客几个月前发布的对于绘制的代码的部分源码解析。

onPause

@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }
        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(r, finished, reason, pendingActions);
        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }
        mSomeActivitiesChanged = true;
    }
}

通过 ActivityThread.handlePauseActivity 最终会导致 onPause 的调用,它会转调到 performPauseActivity 方法:

private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
        PendingTransactionActions pendingActions) {
    // 如果需要 saveState,调用 callActivityOnSaveInstanceState
    final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
    if (shouldSaveState) {
        callActivityOnSaveInstanceState(r);
    }
    // 调用 performPauseActivity
    performPauseActivityIfNeeded(r, reason);
    // ...
    return shouldSaveState ? r.state : null;
}

这里如果我们并非按 back 返回的情况下,mFinished 会为 false,表示此时需要保存 state,如果该 Activity 同时为 Honeycomb (Android 3.0)之前版本的 Activity,则此时就会导致 callActivityOnSaveInstanceState 的调用。(也就是说大部分情况下并不会从这里调用)

之后会调用 performPauseActivityIfNeeded 方法。。

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) {
        // You are already paused silly...
        return;
    }
    try {
        r.activity.mCalled = false;
        // 调用 mInstrumentation.callActivityOnPause
        mInstrumentation.callActivityOnPause(r.activity);
        if (!r.activity.mCalled) {
            throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                    + " did not call through to super.onPause()");
        }
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        if (!mInstrumentation.onException(r.activity, e)) {
            throw new RuntimeException("Unable to pause activity "
                    + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
        }
    }
    r.setState(ON_PAUSE);
}

这里会调用 mInstrumentation.callActivityOnPause 方法对 onPause 进行调用:

public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

最后会调用 Activity.performPause

final void performPause() {
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause();
    mCalled = false;
    onPause();
    mResumed = false;
    if (!mCalled && getApplicationInfo().targetSdkVersion
            >= android.os.Build.VERSION_CODES.GINGERBREAD) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPause()");
    }
    mResumed = false;
}

这里就会对 onPause 进行调用。代表 Activity 已被暂停, Activity 从前台切换到了后台。

onSaveInstanceState

它的调用实际上是从 ActivityThread.performPauseActivity 开始的:

private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
        PendingTransactionActions pendingActions) {
    // 如果需要 saveState,调用 callActivityOnSaveInstanceState
    final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
    if (shouldSaveState) {
        callActivityOnSaveInstanceState(r);
    }
    // 调用 performPauseActivity
    performPauseActivityIfNeeded(r, reason);
    // ...
    return shouldSaveState ? r.state : null;
}

在该方法中,如果用户并非按下 back,则 mFinished 为 false,如果该 ActivityHoneycomb (Android 3.0)之前版本的 Activity,则此时就会导致 callActivityOnSaveInstanceState 的调用。(也就是说大部分情况下并不会从这里调用)

同时,在 ActivityThread.callActivityOnStop 方法中,也会调用 callActivityOnSaveInstanceState 方法:

private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
    // Before P onSaveInstanceState was called before onStop, starting with P it's
    // called after. Before Honeycomb state was always saved before onPause.
    final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
            && !r.isPreHoneycomb();
    final boolean isPreP = r.isPreP();
    if (shouldSaveState && isPreP) {
        callActivityOnSaveInstanceState(r);
    }
    try {
        r.activity.performStop(false /*preserveWindow*/, reason);
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        if (!mInstrumentation.onException(r.activity, e)) {
            throw new RuntimeException(
                    "Unable to stop activity "
                            + r.intent.getComponent().toShortString()
                            + ": " + e.toString(), e);
        }
    }
    r.setState(ON_STOP);
    if (shouldSaveState && !isPreP) {
        callActivityOnSaveInstanceState(r);
    }
}

其中,在用户并非按下 back 的情况下,在 Android P 之前,其调用时间为 onStop 调用之前,在 Android P 之后,其调用时间在 onStop 调用之后

接下来我们看看 callActivityOnSaveInstanceState 的实现:

private void callActivityOnSaveInstanceState(ActivityClientRecord r) {
    r.state = new Bundle();
    r.state.setAllowFds(false);
    if (r.isPersistable()) {
        r.persistentState = new PersistableBundle();
        mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
                r.persistentState);
    } else {
        mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
    }
}

这里调用了 mInstrumentation.callActivityOnSaveInstanceState 方法:

public void callActivityOnSaveInstanceState(Activity activity, Bundle outState) {
    activity.performSaveInstanceState(outState);
}

它调用了 Activity.performSaveInstanceState 方法:

final void performSaveInstanceState(Bundle outState) {
    onSaveInstanceState(outState);
    saveManagedDialogs(outState);
    mActivityTransitionState.saveState(outState);
    storeHasCurrentPermissionRequest(outState);
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
}

最终导致 onSaveInstanceState 的调用并保存了用户的状态。

onStop

通过 ActivityThread.handleStopActivity 最终会调用到 onStop 方法:

@Override
public void handleStopActivity(IBinder token, boolean show, int configChanges,
        PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
    final ActivityClientRecord r = mActivities.get(token);
    r.activity.mConfigChangeFlags |= configChanges;
    final StopInfo stopInfo = new StopInfo();
    performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
            reason);
    if (localLOGV) Slog.v(
        TAG, "Finishing stop of " + r + ": show=" + show
        + " win=" + r.window);
    updateVisibility(r, show);
    // Make sure any pending writes are now committed.
    if (!r.isPreHoneycomb()) {
        QueuedWork.waitToFinish();
    }
    stopInfo.setActivity(r);
    stopInfo.setState(r.state);
    stopInfo.setPersistentState(r.persistentState);
    pendingActions.setStopInfo(stopInfo);
    mSomeActivitiesChanged = true;
}

这里调用了 performStopActivityInner 方法:

private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
        boolean saveState, boolean finalStateRequest, String reason) {
    if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
    if (r != null) {
        if (!keepShown && r.stopped) {
            // ...
        }
        // ...
        if (!keepShown) {
            callActivityOnStop(r, saveState, reason);
        }
    }
}

它最终调用了 callActivityOnStop 方法:

private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
    // Before P onSaveInstanceState was called before onStop, starting with P it's
    // called after. Before Honeycomb state was always saved before onPause.
    final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
            && !r.isPreHoneycomb();
    final boolean isPreP = r.isPreP();
    if (shouldSaveState && isPreP) {
        callActivityOnSaveInstanceState(r);
    }
    try {
        r.activity.performStop(false /*preserveWindow*/, reason);
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        if (!mInstrumentation.onException(r.activity, e)) {
            throw new RuntimeException(
                    "Unable to stop activity "
                            + r.intent.getComponent().toShortString()
                            + ": " + e.toString(), e);
        }
    }
    r.setState(ON_STOP);
    if (shouldSaveState && !isPreP) {
        callActivityOnSaveInstanceState(r);
    }
}

这里就像前面提到的,在 Android 9.0 之前,会在 onStop 之前调用 onSaveInstanceState,而在 Android 9.0 之后则会在 onStop 之后调用 onSaveInstanceState 方法。

onStop 则通过了 Activity.performStop 方法调用:

final void performStop(boolean preserveWindow) {
    mDoReportFullyDrawn = false;
    mFragments.doLoaderStop(mChangingConfigurations /*retain*/);

    // Disallow entering picture-in-picture after the activity has been stopped
    mCanEnterPictureInPicture = false;

    if (!mStopped) {
        // ...
        mInstrumentation.callActivityOnStop(this);
        if (!mCalled) {
            throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onStop()");
        }
                // ...
        mStopped = true;
    }
    mResumed = false;
}

可以看到,它转调到了 mInstrumentation.callActivityOnStop 方法:

public void callActivityOnStop(Activity activity) {
    activity.onStop();
}

其中就会调用 onStop 方法。这时意味着 Activity 从可见变为了不可见。

onDestroy

通过 ActivityThread.handleDestroyActivity 会最终调用到 onDestroy 方法:

@Override
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
        boolean getNonConfigInstance, String reason) {
    // 调用 peformDestroyActivity
    ActivityClientRecord r = performDestroyActivity(token, finishing,
            configChanges, getNonConfigInstance, reason);
    // 对资源进行清理及回收
    if (r != null) {
        // ...
    }
    if (finishing) {
        try {
            ActivityManager.getService().activityDestroyed(token);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
    mSomeActivitiesChanged = true;
}

这里首先调用了 performDestroyActivity,之后对一些资源进行了回收,如对 ContextImpl 进行清理,通知 WindowManagerGlobal 对该 Activity 的信息进行清除等。

ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
        int configChanges, boolean getNonConfigInstance, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    Class<? extends Activity> activityClass = null;
    if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
    if (r != null) {
            // ...
        try {
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnDestroy(r.activity);
            // ...
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException(
                        "Unable to destroy activity " + safeToComponentShortString(r.intent)
                        + ": " + e.toString(), e);
            }
        }
        r.setState(ON_DESTROY);
    }
    mActivities.remove(token);
    StrictMode.decrementExpectedActivityCount(activityClass);
    return r;
}

这里调用了 mInstrumentation.callActivityOnDestroy 方法:

public void callActivityOnDestroy(Activity activity) {      
      activity.performDestroy();
}

它调用了 Activity.performDestroy 方法:

final void performDestroy() {
    mDestroyed = true;
    mWindow.destroy();
    mFragments.dispatchDestroy();
    onDestroy();
    mFragments.doLoaderDestroy();
    if (mVoiceInteractor != null) {
        mVoiceInteractor.detachActivity();
    }
}

在该方法中,对 onDestroy 进行了调用,此时意味着虽然可能 GC 不会马上回收它的内存,但该 Activity 从系统角度来说正式被销毁。

总结

Activity 生命周期的派发基本都是通过 ActivityThreadhandleXXXActivity 实现,其中 ActivityThread 的内部类 H 这个 Handler 负责了它的所有消息处理过程,消息都会到达该 Handler 并由它进行派发。并且 Activity 的生命周期调用之前都会通过 mInstrumentation 进行转调,从而实现统一管理,便于后续维护。

创建

Activity 创建由 ActivityThread.handleLaunchActivity 的调用开始,它会调用到 peformLaunchActivity,其中主要分为三步:

  1. 通过 mInstrumentation.newActivity 构造一个 Activity 对象,它是通过反射构造。
  2. 获取 Application 并调用 activity.attach,其中会完成 ContextImpl 的设置以及 PhoneWindow 的创建,PhoneWindow 中会对 DecorView 进行创建。
  3. 通过 mInstrumentation.callActivityOnCreate 调用 Activity.peformCreate 方法。

onCreate

ActivityonCreate 意味着 Activity 由未创建变为了已创建,此时 Activity 已经创建。此时 Activity 还不可见,在其中往往会调用 setContentView 方法,对 XML 进行解析并进行 View 对象的创建,同时一些初始化操作往往也在 onCreate 中进行。

onStart

ActivityonStart 意味着 Activity 从不可见变为了可见,此时已经可见,只是还没有显示在前台。虽然 onStart 也能进行初始化操作但我们往往在 onCreate 中进行。

onStart 调用后,若 Activity 存在未恢复的状态,会通过 mInstrumentation.callActivityRestoreInstanceState 调用 onRestoreInstanceState

onRestoreInstanceState

Activity 之前被异常关闭后,会通过该方法对之前保存的信息进行恢复。ActivityonRestoreInstanceState 往往在 onStart 之后调用,我们可以在其中对异常关闭在 onSaveInstanceState 中保存的状态进行恢复。

onResume

ActivityonResume 意味着 Activity 从后台转变到了前台,已处于前台并可见

同时,onResume 调用完成后,若 ActivityPhoneWindow 还没有通过 WindowManager 添加,会通过 wm.addViewDecorView 添加到 WindowManager,这里就是 Activity 被绘制的入口。

绘制

绘制会在 onResume 调用之后,若 ActivityPhoneWindow 还没有通过 WindowManager 添加时通过 wm.addView 触发,其出发的核心是由于添加 View 导致了 ViewRootImpl 的创建,之后其 setView 方法调用了 requestLayout 方法从而使得绘制开始执行。

onPause

ActivityonPause 意味着 Activity 从前台转变到了后台,该方法不能执行太耗时的操作

同时,如果在 Android 3.0 之前,若用户并非按 back 返回(如被异常销毁等情况),则会在 onPause 调用之前调用 onSaveInstanceState

onSaveInstanceState

Activity 并非用户主动关闭而是一些异常情况下时,会调用此方法对 Activity 中的信息进行保存。

比较特别的是,这个方法的调用时机与 Android 版本有关

  • Android 3.0 之前,它会在 onPause 之前调用
  • Android 9.0 之前,它会在 onStop 之前调用
  • Android 9.0 之后,它会在 onStop 之后调用

onStop

ActivityonStop 意味着 Activity 从可见变为了不可见

onStop 前后会根据 Android 版本调用 onSaveInstanceState 方法。

onDestroy

ActivityonDestroy 意味着虽然可能 GC 不会马上回收它的内存,但该 Activity 从系统角度来说正式被销毁

相关问题

  • onSaveInstanceState 方法在 Activity 的哪两个生命周期方法之间调用?
    • Android 3.0 之前在 onPause 之前调用。
    • Android 9.0 之前在 onStop 之前调用。
    • Android 9.0 之后在 onStop之后调用。
  • 弹出一个 Dialog 时,onPause 会调用吗?什么情况下会,什么情况下不会?
    • 如果弹出的是本 Activity 的 Dialog,不会有任何生命周期方法调用。因为 Dialog 是一个 View,本身就依附在 Activity上,它的焦点也是本 Activity 的焦点。如果其他 Activity 的 Dialog 弹出了,onPause 才会调用
  • 横竖屏切换的时候,生命周期方法是如何调用的?如何进行配置呢?
    • 横竖屏切换时,如果不做任何配置,会导致 Activity 重建,生命周期方法的回调顺序为:onPause --> onSaveInstanceState --> onStop --> onDestroy --> onCreate --> onStart --> onRestoreInstanceState --> onResume
  • 在onCreate或者onRestoreInstance方法中恢复数据时,有什么区别?
    • onRestoreInstance 调用时,其中的 Bundle 参数必然不为空。onCreate 恢复数据时,Bundle 参数可能为空,需要额外判断。
  • Activity调用了onDestory方法,就会在Activity的任务栈消失吗?
    • 如果点击 back 导致了 onDestroy 被调用,相当于是调用了 finish 导致其被调用,此时它会从返回栈移除。但如果直接调用 onDestroy 方法,则 Activity 不会从返回栈移除
  • Activity A 启动 Activity B,生命周期是怎样的?
    • 启动时 A.onPause --> B.onCreate --> B.onStart --> B.onResume --> A.onStop
    • 返回时 B.onPause --> A.onRestart/A.onCreate --> A.onStart --> A.onResume --> B.Stop(若 A 未被销毁,则 A.onRestart,否则 A.onCreate
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注

%d 博主赞过: