从源码看 Activity 生命周期(上篇)

本文是个人 AOSP 系列 第六篇文章,往期目录以下:java

Java 世界的盘古和女娲 —— Zygoteandroid

Zygote家的大儿子 —— SystemServergit

Android 世界中,谁喊醒了 Zygote ?github

“无处不在” 的系统核心服务 —— ActivityManagerService 启动流程解析数据库

庖丁解牛Activity 启动流程服务器

一路从 Zygote 说到 SystemServer ,从 AMS 的启动流程 说到 应用进程的建立,再到上一期的 Activity 启动流程,今天准备来讲说你们耳熟能详的 Activity 的生命周期。关于生命周期的基础知识,官网上的这篇文章 了解 Activity 的生命周期 已经做了详细介绍。在本文中,我会从源码角度来切入生命周期的调用流程。微信

提到 Android 官网的 文档 部分,我想多说一句。不论是新知识点,仍是你已经掌握的内容,这里都是一份绝佳的资料库。我如今每复习一个知识点,都会去重读一遍官网文档,总能有不同的收货,文末也贴出了个人阅读笔记。网络

再回到本文来,其实若是有仔细阅读上一篇文章 庖丁解牛Activity 启动流程 的话,里面已经较为详细的介绍了生命周期的调用流程。只是上篇文章阅读体验的确不怎么好,因此这里把 Activity 的生命周期 单独拎出来讲一说。app

首先来看下 Google 给出的 Activity 经典生命周期图:async

(

这张图应该没什么好说的了,你们确定了如指掌。可是你了解每一个生命周期背后的调动流程吗?

经过上篇文章咱们都知道了 Activity 的启动由应用进程发起,经过 Binder 调用 AMS 完成,那么 AMS 所在进程是如何回调到到应用进程的生命周期方法的呢?

其实图中的每个生命周期方法的调用流程都是同一个套路,大同小异,先搞清楚这个套路,其余问题就迎刃而解了。

生命周期的调用套路

为了方便讲解,咱们以 Activity 最早被调用的生命周期 onCreate() 为例。

回顾 Activity 的启动流程,最后会调用到 ActivityStackSupervisorrealStartActivityLocked() 方法。

> ActivityStackSupervisor.java final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {

    ......

    
    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
    // 1. 添加 LaunchActivityItem callback
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                System.identityHashCode(r), r.info,
                mergedConfiguration.getGlobalConfiguration(),
                mergedConfiguration.getOverrideConfiguration(), r.compat,
                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                profilerInfo));

     final ActivityLifecycleItem lifecycleItem;
     if (andResume) {
         lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    // 2. 设置生命周期状态
     clientTransaction.setLifecycleStateRequest(lifecycleItem);

    // 3. 调用 ClientLifecycleManager.scheduleTransaction()
     mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ......
    return true;
}
复制代码

已省略大量无关代码。

上述代码中构建了一个 ClientTransaction 对象,分别调用了它的 addCallback()setLifecycleStateRequest() 方法,最后调动 schchueduleTransaction 执行构造的 ClientTransaction 对象,分别对应注释的 123 处。下面来看一下这三个方法。

ClientTransaction.addCallback()

> ClientTransaction.java public void addCallback(ClientTransactionItem activityCallback) {
        if (mActivityCallbacks == null) {
            mActivityCallbacks = new ArrayList<>();
        }
        mActivityCallbacks.add(activityCallback);
    }
复制代码

mActivityCallbacks 是元素类型为 ClientTransactionItem 的集合。addCallback() 传入的参数是 LaunchActivityItem , 正是 ClientTransactionItem 的实现类。

ClientTransaction.setLifecycleStateRequest()

> ClientTransaction.java public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
        mLifecycleStateRequest = stateRequest;
    }
复制代码

mLifecycleStateRequest 表示当前的 ClientTransaction 执行以后应该处于的最终生命周期状态。

ClientLifecycleManager.scheduleTransaction()

注释 3 处 mService.getLifecycleManager().scheduleTransaction(clientTransaction);mService.getLifecycleManager() 返回的是 ClientLifecycleManager 对象,是 Android 9.0 新增的辅助处理生命周期的类,以往的源码中是没有的。看一下它的 scheduleTransaction() 方法。

> ClientLifecycleManager.java void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient(); // -> ApplicationThread
        transaction.schedule(); // ClientTransaction
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }
复制代码

调用了 ClientTransactionschedule() 方法。

> ClientTransaction.java public void schedule() throws RemoteException {
        // 调用 ActivityThread.ApplicationThread.scheduleTransaction()
        mClient.scheduleTransaction(this);
    }
复制代码

首先明确一点,到目前为止的方法调用都处于 AMS 所在进程,并非咱们的应用进程。那么 mClient 是什么呢?java

private IApplicationThread mClient;
复制代码

IApplicationThread 是极其重要的一个 Binder 接口,它维护了应用进程和 AMS 的之间的通信。这个 mClient 就是应用进程在 AMS 进程中的代理对象,AMS 经过 mClient 来指挥应用进程。

mClient 只是 AMS 进程中的一个 "傀儡" ,它的真身是 ActivityThread.ApplicationThread

private class ApplicationThread extends IApplicationThread.Stub {
        ......
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            // 这里调用的是父类 ClientTransactionHandler 的 scheduleTransaction() 方法
            ActivityThread.this.scheduleTransaction(transaction);
        }
        ......
}
复制代码

ActivityThread 并无 scheduleTransaction() 方法,因此调用的是其父类 ClientTransactionHandler 的相应方法。

> ClientTransactionHandler.java void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);java
        // sendMessage() 方法在 ActivityThread类中实现
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
复制代码

ClientTransactionHandler 是一个抽象类,sendMeschusage() 也是一个抽象方法,其具体实如今 ActivityThread 类中,记住其参数 ActivityThread.H.EXECUTE_TRANSACTION

> ActivityThread.java private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);java
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);chu
        }
        mH.sendMessage(msg);
    }
复制代码

其中的 mH 是 ActivityThread 的内部类 H ,是一个 Handler 对象。咱们都知道 Handler 是用于线程间通信的,那么这里是哪两个线程之间呢?AMS 经过 Binder 调用应用进程的对应方法,执行的是应用进程的 Binder 线程,而真正须要回调生命周期的是 主线程 ,因此这里进行通信的就是 Binder 线程 和 主线程。

class H extends Handler {
        
        public void handleMessage(Message msg) {
            ......
             case EXECUTE_TRANSACTION:chu
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    // 执行 TransactionExecutor.execute()
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        transaction.recycle();
                    }
                    break;
            ......
        }
}
复制代码

获取到 AMS 发送过来的 ClientTransaction 对象,调用 TransactionExecutorexecute() 方法来执行这次事务。

> TransactionExecutor.java public void execute(ClientTransaction transaction) { clientTransaction.setLifecycleStateRequest(lifecycleItem);
        executeCallbacks(transaction);

        // 执行生命周期状态
        executeLifecycleState(transaction);

    }
复制代码

看到 execute() 中的两个方法,你应该有种似曾相识的感受。回到文章开头处 ActivityStackSupervisorrealStartActivityLocked() 方法 :

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {

    ......

    // 1. addCallback()
    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
    clientTransaction.addCallback(LaunchActivityItem.obtain(new ...


    // 2. setLifecycleStateRequest
         final ActivityLifecycleItem lifecycleItem;
     if (andResume) {
         lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
     clientTransaction.setLifecycleStateRequest(lifecycleItem);

    // 3. 调用 ClientLifecycleManager.scheduleTransaction()
     mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ......
    return true;
}
复制代码

addCallback() >>> executeCallbacks()

setLifecycleStateRequest >>> executeLifecycleState()

executeCallbacks() 会执行 addCallback() 方法添加的生命周期回调。当前添加的是 LaunchActivityItem

executeLifecycleState() 方法会将当前生命周期同步到 setLifecycleStateRequest() 方法设置的生命周期状态。当前设置的是 ResumeActivityItem

从源码来看看这两个方法是如何执行的。

TransactionExecutor.executeCallbacks()

> TransactionExecutor.java public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();

        ......

        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            ......
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ......
        }
    }
复制代码

获取全部的 callback 并循环调用 execute()postExecute() 方法。这里的 calkback 只有一个元素 LaunchActivityItem

public class LaunchActivityItem extends ClientTransactionItem {
    @Override
    public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        // 调用 ActivityThread.handleLaunchActivity()
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    }
}
复制代码

构建了 ActivityClientRecord 对象,接着调用 ActivityThreadhandleLaunchActivity() 方法。

> ActivityThread.java

    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
        ......

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        WindowManagerGlobal.initialize();

        final Activity a = performLaunchActivity(r, customIntent);activityIdleInternalLocked

        ......

        return a;
    }
复制代码

performLaunchActivity() 上篇文章已经详细介绍过,下面代码中仅保留生命周期相关代码。

> ActivityThread.java private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;

        // 获取 Context
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;

        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 反射建立 Activity
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);

        // 获取 Application系统永远不会直接终止 Activity 以释放内存,而是会终止 Activity 所在的进程。系统不只会销毁 Activity,还会销毁在该进程中运行的全部其余内容。
        if (activity != null) {activityIdleInternalLocked

            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embedded  // 获取 Context
                    CID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback);


            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                // 设置主题
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            // 执行 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);


        return activity;
    }
复制代码

重点关注 mInstrumentation.callActivityOnCreate()Instrumentation 是个很重要的类,它在 Activity 的启动,生命周期管理中都承担了重要的角色。

> Instrumentation.java public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
复制代码
> Activity.java final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        // 执行 onCreate()
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ......
    }
复制代码

最终终于执行到了 Activity 的 onCreate() 方法,executeCallbacks() 方法也就到此结束了。固然,onCreate() 并非一个长久存在的状态,那么如何过渡到下一个生命周期呢?来看看 executeLifecycleState() 方法。

TransactionExecutor.executeLifecycleState()

> TransactionExecutor.java private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }

        ......

        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
复制代码

executeLifecycleState() 方法的参数是 ResumeActivityItem ,方法体内直接调用其 execute() 方法。

> ResumeActivityItem.java

    @Override
    public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
    }
复制代码

能够看到和 onCreate() 的套路是如出一辙的,调用 ActivityThread.handleResumeActivity() ,接着是 Instrumentation.callActivityOnResume() ,最后回调 Activity.onResume()

一个生命周期又完成了,onResume() 是一个相对能够长期存在的生命周期状态。

TransactionExecutor.cycleToPath()

等等,有没有感受哪里不对劲?onStart() 哪里去了?

正常的生命周期流程应该是 onCreate() -> onStart() -> onResume() ,可是代码中好像又没有显示调用。实际上是在 executeLifecycleState() 中的 cycleToPath() 方法中作了生命周期的同步。简单说就是,当前处于 onCreate() 状态,setLifecycleState() 设置的 final stateonResume() ,就须要执行 onCreate 到 onResume 之间的状态,即 onStart() 。下面简单看下源码。

> TransactionExecutor.java private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState) {
        final int start = r.getLifecycleState();
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path);
    }
复制代码

getLifecyclePath() 方法就是根据 startfinish 计算出中间的生命周期路径。这里计算出来就是 ON_START

> TransactionExecutor.java private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            log("Transitioning to state: " + state);
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");> TransactionExecutor.java
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r.token, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }
复制代码

找到 ON_START 分支,调用了 ActivityThread.handleStartActivity() 方法,又是同样的套路了,这里就再也不赘述了。

依次类推,ActivityThread 中应该有以下方法:

handleLaunchActivity()
handleStartActivity()
handleResumeActivity()
handlePauseActivity()
handleStopActivity()
handleDestroyActivity()
复制代码

写到这,已经分析完了 onCreate()onStart()onResume() 这三个生命周期的调用时机和流程,剩下的 onPauseonStoponDestroy() 就放到下篇文章再说吧。

给你们分享一下我阅读 Activity 生命周期相关官方文档的一些笔记。

onCreate

您必须实现此回调,其在系统首次建立 Activity 时触发。Activity 会在建立后进入已建立状态。该逻辑在 Activity 的整个生命周期中只应发生一次。

onStart

当 Activity 进入“已开始”状态时,系统会调用此回调。onStart() 调用使 Activity 对用户可见,由于应用会为 Activity 进入前台并支持交互作准备。

onStart() 方法会很是快速地完成,而且与“已建立”状态同样,Activity 不会一直处于“已开始”状态。一旦此回调结束,Activity 便会进入已恢复状态,系统将调用 onResume() 方法。

onResume

Activity 会在进入“已恢复”状态时来到前台,而后系统调用 onResume() 回调。这是应用与用户交互的状态。应用会一直保持这种状态,直到某些事件发生,让焦点远离应用。

onPause

系统将此方法视为用户正在离开您的 Activity 的第一个标志(尽管这并不老是意味着活动正在遭到销毁);此方法表示 Activity 再也不位于前台(尽管若是用户处于多窗口模式,Activity 仍然可见)。

onPause() 执行很是简单,并且不必定要有足够的时间来执行保存操做。所以,您不该使用 onPause() 来保存应用或用户数据、进行网络调用,或执行数据库事务。由于在该方法完成以前,此类工做可能没法完成。

完成 onPause() 方法并不意味着 Activity 离开“已暂停”状态。相反,Activity 会保持此状态,直到其恢复或变成对用户彻底不可见。

onStop

若是您的 Activity 再也不对用户可见,则说明其已进入已中止状态,所以系统将调用 onStop() 回调。

在 onStop() 方法中,应用应释放或调整应用对用户不可见时的无用资源。

您还应该使用 onStop() 执行 CPU 相对密集的关闭操做。

进入“已中止”状态后,Activity 要么返回与用户交互,要么结束运行并消失。

onDestroy

销毁 Ativity 以前,系统会先调用 onDestroy()。系统调用此回调的缘由以下:

  1. Activity 正在结束(因为用户完全关闭 Activity 或因为系统为 Activity 调用 finish()
  2. 因为配置变动(例如设备旋转或多窗口模式),系统暂时销毁 Activity

系统永远不会直接终止 Activity 以释放内存,而是会终止 Activity 所在的进程。系统不只会销毁 Activity,还会销毁在该进程中运行的全部其余内容。

最后

目前为止,咱们已经深刻探讨了 Activity 的启动流程,Activity 的生命周期流程。可是关于 Activity 的知识点实在是有点多。

Activity 是什么?Activity 由什么组成?Activity 是如何显示到屏幕上的?

目测还能够再为 Activity 写四五篇文章,敬请期待。

---- 分割线

买了一个服务器,准备用 Halo 搭建我的博客,好好整理一下以前写过的各个系列的文章。求推荐域名! 求推荐域名! 求推荐域名!

文章首发微信公众号: 秉心说 , 专一 Kotlin、 Java 、 Android 原创知识分享,AOSP 源码解析。

更多最新原创文章,扫码关注我吧!

相关文章
相关标签/搜索