【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个生命周期的处理流程。

相关推荐
bianshaopeng11 分钟前
android 原生加载pdf
android·pdf
hhzz19 分钟前
Linux Shell编程快速入门以及案例(Linux一键批量启动、停止、重启Jar包Shell脚本)
android·linux·jar
火红的小辣椒1 小时前
XSS基础
android·web安全
勿问东西3 小时前
【Android】设备操作
android
五味香3 小时前
C++学习,信号处理
android·c语言·开发语言·c++·学习·算法·信号处理
图王大胜5 小时前
Android Framework AMS(01)AMS启动及相关初始化1-4
android·framework·ams·systemserver
工程师老罗7 小时前
Android Button “No speakable text present” 问题解决
android
小雨cc5566ru8 小时前
hbuilderx+uniapp+Android健身房管理系统 微信小程序z488g
android·微信小程序·uni-app
小雨cc5566ru9 小时前
微信小程序hbuilderx+uniapp+Android 新农村综合风貌旅游展示平台
android·微信小程序·uni-app
小雨cc5566ru9 小时前
小程序 uniapp+Android+hbuilderx体育场地预约管理系统的设计与实现
android·小程序·uni-app