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

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

-- 服装学院的IT男
本篇已收录于Activity短暂的一生系列

欢迎一起学习讨论Android应用开发或者WMS

V:WJB6995

Q:707409815

正文

生命周期系列:

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

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

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

1. 启动流程介绍

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

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

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

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

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

开始撸代码

复制代码
# 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 到底是什么

复制代码
# 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 方法是如何触发对应事务执行的。

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

复制代码
# 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

复制代码
# 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 中。

复制代码
# 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 中处理了。

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

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

2.3.1 executeCallbacks 和 executeLifecycleState 方法

为什么我在上面注释里说 executeCallbacks 是处理 LaunchActivityItem,executeLifecycleState 是处理 ResumeActivityItem 呢?

代码中有答案:

复制代码
# 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个事务的处理如下:

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

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

2.4 小结

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

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

复制代码
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个生命周期的处理流程。

相关推荐
恋猫de小郭4 分钟前
注意,暂时不要升级 MacOS ,Flutter/RN 等构建 ipa 可能会因 「ITMS-90048」This bundle is invalid 被拒绝
android·前端·flutter
每次的天空6 小时前
Android学习总结之算法篇五(字符串)
android·学习·算法
Gracker7 小时前
Android Weekly #202513
android
张拭心9 小时前
工作九年程序员的三月小结
android·前端
每次的天空9 小时前
Flutter学习总结之Android渲染对比
android·学习·flutter
鸿蒙布道师12 小时前
鸿蒙NEXT开发土司工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
智想天开12 小时前
11.使用依赖注入容器实现松耦合
android
yunteng52113 小时前
音视频(四)android编译
android·ffmpeg·音视频·x264·x265
tangweiguo0305198713 小时前
(kotlin) Android 13 高版本 图片选择、显示与裁剪功能实现
android·开发语言·kotlin
匹马夕阳13 小时前
(一)前端程序员转安卓开发分析和规划建议
android·前端