当前位置: 首页 > article >正文

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

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。
                  
                  
                                           – 服装学院的IT男

本篇已收录于Activity短暂的一生系列
欢迎一起学习讨论Android应用开发或者WMS
V:WJB6995
Q:707409815

正文

在这里插入图片描述
生命周期系列:

  • Activity生命周期之onPause

  • onCreate,onStart,onResume-1

  • onCreate,onStart,onResume-2

  • Activity生命周期之onStop-1

  • Activity生命周期之onStop-2

  • Activity生命周期之onDestory

在整个启动流程中,上一篇介绍了第一阶段: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个生命周期的处理流程。


http://www.kler.cn/a/329099.html

相关文章:

  • 【小程序】dialog组件
  • 【分布式技术】ES扩展知识-Elasticsearch分词器的知识与选择
  • Jaskson处理复杂的泛型对象
  • 【原创】如何备份和还原Ubuntu系统,非常详细!!
  • 浅谈数据仓库的架构及其演变
  • 阿里云引领智算集群网络架构的新一轮变革
  • 计算机网络:计算机网络概述 —— 初识计算机网络
  • 盒子是什么? -- 第四课
  • Meta推出Llama 3.2 AI模型,支持多模态和边缘计算;OpenAI首席技术官穆拉蒂宣布离职
  • 数据链路层 ——MAC
  • 设计模式——责任链模式
  • 螺狮壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习03(网络及IP规划)
  • AI 对话工具汇总
  • vulnhub-DarkHole 1靶机的测试报告
  • 想知道为什么有DICOM格式,YAML格式,XML格式,JSON格式吗?
  • OSI 七层模型和TCP/IP 四层模型的区别
  • PG数据库的Jsonb全文检索查询
  • 【React】useState 和 useRef:项目开发中该如何选择
  • R开头的后缀:RE
  • C++平台跳跃游戏
  • 智慧环保大数据平台建设方案
  • Windows 开发工具使用技巧 Visual Studio使用安装和使用技巧 Visual Studio 快捷键
  • httpsok-v1.17.0-SSL通配符证书自动续签
  • css-容器高度百分比(%),容器内的文字垂直居中
  • 梳理相关新闻报道:Linux惊现9.9分灾难级漏洞
  • Linux篇之IO多路复用