【Android 13源码分析】Activity生命周期之onCreate,onStart,onResume-1

忽然有一天,我想要做一件事:去代码中去验证那些曾经被"灌输"的理论。

-- 服装学院的IT男

在整个启动流程中,上一篇介绍了第一阶段:SourceActivity 的 onPause

现在分析第二阶段:TargetActivity 启动后会依次执行 onCreate,onStart,onResume。

另外还会完整的介绍一下 Activity 生命周期的事务是如何触发的。

由于篇幅原因,分为以下2篇:

Activity生命周期之onCreate,onStart,onResume-1

Activity生命周期之onCreate,onStart,onResume-2

1. 启动流程介绍

我们知道 onCreate 这个生命周期表示 Activity 的创建,对应 LaunchActivityItem 这个事务,源码中构建这个事务唯一的地方就在 ActivityTaskSupervisor::realStartActivityLocked 方法。

而 ActivityTaskSupervisor::realStartActivityLocked 方法的执行逻辑,在Activity启动流程系列说过要启动 TargetActivity 有2个必要条件:

    1. TargetActivity 所在的应用进程已经启动
    1. SourceActivity 需要执行 onPause

不考虑异常情况,能执行 onCreate 的场景就是冷热启动了,冷热启动区别也就在于多了个需要创建应用进程,不过最终都会执行到 ActivityTaskSupervisor::realStartActivityLocked 方法。

无论是启动进程后执行过来的,还是上篇提到的 SourceActivity 执行 activityPaused 流程触发过来的结果都是一样的,不必太在意

开始撸代码

scss 复制代码
# ActivityTaskSupervisor 

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
            // 1. 判断是否执行完了pause 。 也就是2个条件之一,必须要执行完pause才可以进入后面
            if (!mRootWindowContainer.allPausedActivitiesComplete()) {
                // While there are activities pausing we skipping starting any new activities until
                // pauses are complete. NOTE: that we also do this for activities that are starting in
                // the paused state because they will first be resumed then paused on the client side.
                // 不满足添加就打log
                ProtoLog.v(WM_DEBUG_STATES,
                        "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
                        r);
                return false;
            }
            ......
                // 2. wm_restart_activity 
                EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
                        task.mTaskId, r.shortComponentName);
                
                // 3.重点* 创建Activity启动事务.将构建的 LaunchActivityItem 添加到 clientTransaction 中
                final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.token);
                ......
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                        results, newIntents, r.takeOptions(), isTransitionForward,
                        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                        r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
                        
               
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    // 4.重点*. 设置预期的最终状态Resume逻辑,启动走的这。 表示需要执行到onCreate
                    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
                } else {
                    //  Pause 逻辑
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);
                // 5.重点* 调度事务,将clientTransaction添加到生命周期管理器中
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    }
    1. 如果有Activity没有执行完 pause ,则不能执行新的Activity的启动。 如果不满足条件也会相应的ProtoLog
    1. 打印Events日志,格式为:wm_restart_activity: [0,253598020,21,com.google.android.dialer/.extensions.GoogleDialtactsActivity]
    1. 构建 LaunchActivityItem 事务,将会触发创建Activity,并执行到 onCreate
    1. 构建 ResumeActivityItem 事务,将会触发执行到Activity的 onResume
    1. 执行事务

后面的流程其实可以直接去看应用端这2个事务的执行,不过我对这中间的调用比较好奇,所以把生命周期跨进程调用事务的逻辑也梳理了一遍。对这块比较了解的可以跳过,直接看第三章生命周期相关的内容

2. Activity 生命周期事务跨进程处理方式详解

2.1 了解ClientTransaction

在 ActivityTaskSupervisor::realStartActivityLocked 方法中对跨进程执行生命周期事务的代码可以归纳为以下几步:

    1. 构建出 ClientTransaction
    1. 构建 onCreate 和 onResume对应的2个事务,并保存到 ClientTransaction 中
    1. 通过 ClientLifecycleManager::scheduleTransaction 方法来触发事务的调度执行,唯一参数就是 ClientTransaction

这一小节先来了解一下这个 ClientTransaction 到底是什么

csharp 复制代码
# ClientTransaction
    // 实现Parcelable接口,说明可序列化
    public class ClientTransaction implements Parcelable, ObjectPoolItem {
        // 几个重要的成员变量
        private List<ClientTransactionItem> mActivityCallbacks;
        private ActivityLifecycleItem mLifecycleStateRequest;
        // 目标进程
        private IApplicationThread mClient;
        // 目标Activity
        private IBinder mActivityToken;

        // client :对应进程
        // activityToken :创建ActivityRecord时的匿名token
        public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
            ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
            if (instance == null) {
                instance = new ClientTransaction();
            }
            instance.mClient = client;
            instance.mActivityToken = activityToken;

            return instance;
        }

        // 拿到对应
        public IBinder getActivityToken() {
            return mActivityToken;
        }

        public void addCallback(ClientTransactionItem activityCallback) {
            if (mActivityCallbacks == null) {
                mActivityCallbacks = new ArrayList<>();
            }
            // 事务添加到 mActivityCallbacks 列表中
            mActivityCallbacks.add(activityCallback);
        }

        // 事务赋值给 mLifecycleStateRequest 变量
        public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
            mLifecycleStateRequest = stateRequest;
        }
        // 目标进程执行事务
        public void schedule() throws RemoteException {
            mClient.scheduleTransaction(this);
        }
    }

ClientTransaction 的核心方法就这些,结合 ActivityTaskSupervisor::realStartActivityLocked 方法的使用得出以下结论:

    1. ClientTransaction::obtain 构建出一个 ClientTransaction 对象,2个参数分别为目标进程,和目标Activity
    1. addCallback 方法会将 LaunchActivityItem 放到 内部的 mActivityCallbacks 列表中
    1. setLifecycleStateRequest 方法将 ResumeActivityItem 事务赋值给了 mLifecycleStateRequest 变量。

这里还有个重要的方法 schedule() ,最终会触发目标进程执行当前这个 ClientTransaction 。

2.2 事务的调度执行

上一小节知道生命周期的事务都被包装在了一个 ClientTransaction 对象中,现在来看看 ClientLifecycleManager::scheduleTransaction 方法是如何触发对应事务执行的。

该方法有多个重载,但是本质都一样

less 复制代码
# ClientLifecycleManager
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        // 重点* 调用ClientTransaction::schedule
        transaction.schedule();
        ......
    }

    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        //  构建 一个 ClientTransaction,调用上面的scheduleTransaction
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }
    ......忽略另外几个重载, 都是内部构建出一个 ClientTransaction 

主要就是执行了 ClientTransaction::schedule 方法。

2.3 应用进程处理

ClientTransaction::schedule 方法会跨进程调用到目标进程的 scheduleTransaction 方法,我们知道进程指的就是 ActivityThread 内部类 ApplicationThread

csharp 复制代码
# ActivityThread$ApplicationThread
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            // 这里调用的是ActivityThread的父类 ClientTransactionHandler
            ActivityThread.this.scheduleTransaction(transaction);
        }

# ClientTransactionHandler
    void scheduleTransaction(ClientTransaction transaction) {
        // 执行 preExecute (预执行)
        transaction.preExecute(this);
        // 重点* 发送消息
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

先执行 preExecute 方法,最重要的是执行发送了一个 EXECUTE_TRANSACTION 消息,并把 ClientTransaction 传过去了。

这个消息的处理在 ActivityThread 中。

scala 复制代码
# ActivityThread
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    class H extends Handler {

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                ......
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    // 处理
                    mTransactionExecutor.execute(transaction);
                    ......
                    break;
                ......
            }
        }
    }

ClientTransaction 又被传递到 TransactionExecutor 中处理了。

scss 复制代码
# TransactionExecutor
    public void execute(ClientTransaction transaction) {
        ......
        // LaunchActivityItem
        executeCallbacks(transaction);

        // ResumeActivityItem
        executeLifecycleState(transaction);
        ......
    }

2.3.1 executeCallbacks 和 executeLifecycleState 方法

为什么我在上面注释里说 executeCallbacks 是处理 LaunchActivityItem,executeLifecycleState 是处理 ResumeActivityItem 呢? 代码中有答案:

java 复制代码
# TransactionExecutor
    public void executeCallbacks(ClientTransaction transaction) {
        // 获取 callback 的元素,没有就返回
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null || callbacks.isEmpty()) {
            // No callbacks to execute, return early.
            return;
        }
        ......
        // 当前场景是触发 LaunchActivityItem的execute方法
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        ......
    }


    private void executeLifecycleState(ClientTransaction transaction) {
        // 获取tLifecycleStateRequest,没有就返回
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        ......
        // 重点* 将Activity的状态转换至接近最终目标状态的位置  也就是会触发onStart
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

        // Execute the final transition with proper parameters.
        // 当前场景是触发LaunchActivityItem的execute
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

而之前SystemService对这2个事务的处理如下:

lua 复制代码
ActivityTaskSupervisor::realStartActivityLocked
    LaunchActivityItem.obtain   -- 添加到事务到 mActivityCallbacks 列表
    ResumeActivityItem.obtain   -- 设置事务到 mLifecycleStateRequest
    ClientLifecycleManager::scheduleTransaction  -- 触发事务的执行

所以说:executeCallbacks 方法是处理 LaunchActivityItem,executeLifecycleState 是处理 ResumeActivityItem。

2.4 小结

经过上面这些分析,我们知道在 ActivityTaskSupervisor::realStartActivityLocked 方法中启动 Activity 就是构建了2个事务到 ClientTransaction 中,并跨进程到目标进程执行。

2个事务从SystemService进程到目标应用进程完整的调用链如下:

php 复制代码
ActivityTaskSupervisor::realStartActivityLocked
    ClientTransaction::obtain             -- 构建客户端事务
    LaunchActivityItem::obtain            -- 构建 onCreate 启动事务
    ClientTransaction::addCallback        -- onCreate事务添加进回调
    ResumeActivityItem::obtain            -- 构建 onResume 事务
    ClientTransaction::setLifecycleStateRequest  --  onResume 事务添加进LifecycleStateRequest
    ClientLifecycleManager::scheduleTransaction  -- 执行事务
        ClientTransaction::schedule               -- 触发目标进程执行
            ActivityThread$ApplicationThread::scheduleTransaction  -- 进入应用进程
                ClientTransactionHandler::scheduleTransaction
                    ClientTransaction::preExecute
                    ActivityThread::sendMessage                     -- 发送"EXECUTE_TRANSACTION"消息
                        ActivityThread$H::handleMessage 
                            TransactionExecutor::execute
                                TransactionExecutor::executeCallbacks        -- LaunchActivityItem 事务
                                    LaunchActivityItem::execute              -- 触发 onCreate
                                    LaunchActivityItem::postExecute
                                TransactionExecutor::executeLifecycleState   -- ResumeActivityItem 事务
                                    TransactionExecutor::cycleToPath         -- 触发 onStart
                                    ResumeActivityItem::execute              -- 触发 onResume
                                    ResumeActivityItem::postExecute

时序图如下:

可以看到从 生命周期事务的执行到真正触发其 execute 方法,中间的调用链还是很长的,不过这个流程也不算很重要,一般看到 ResumeActivityItem 这种事务构建了,直接去看对应的 execute,postExecute 等方法就好了。

从调用链上也看到了 3个生命周期的执行顺序和期望的log打印也是一样的,当然具体是怎么执行到的要看后续代码分析。

3. 总结

这一篇对介绍了 Activity 启动流程中 SystemService 端末尾的工作, 另外介绍了一下 Activity 生命周期事务跨进程处理方式,关于onCreate,onStart,onResume 这3个生命周期在SystemService 端的流程介绍完了,下一篇是重点,会详细介绍在应用端对这3个生命周期的处理流程。

相关推荐
H1005 分钟前
重构(二)
android·重构
拓端研究室15 分钟前
R基于贝叶斯加法回归树BART、MCMC的DLNM分布滞后非线性模型分析母婴PM2.5暴露与出生体重数据及GAM模型对比、关键窗口识别
android·开发语言·kotlin
中草药z22 分钟前
【Spring】深入解析 Spring 原理:Bean 的多方面剖析(源码阅读)
java·数据库·spring boot·spring·bean·源码阅读
zhangphil1 小时前
Android简洁缩放Matrix实现图像马赛克,Kotlin
android·kotlin
m0_512744641 小时前
极客大挑战2024-web-wp(详细)
android·前端
lw向北.1 小时前
Qt For Android之环境搭建(Qt 5.12.11 Qt下载SDK的处理方案)
android·开发语言·qt
不爱学习的啊Biao2 小时前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
Clockwiseee2 小时前
PHP伪协议总结
android·开发语言·php
mmsx9 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
众拾达人12 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言