irpas技术客

App 启动流程与 Activity 启动流程梳理_DDDevoli

irpas 5399

目录 前言流程图启动流程第一阶段(Launcher 向 AMS 发送启动请求)第二阶段(AMS 启动 Activity, 并告知 Launcher pasue)第三阶段 (App 进程的 Activity 启动流程) 总结

前言

作记录用,流程图部分可以参考学习,其余部分都还很粗糙,细节也没有理解到位,不足以作为参考,待继续完善!(推荐阅读第五篇参考博文,介绍比较清楚,提纲挈领)

本文主要依据 Android S 源码梳理 Activity 的启动流程,详细源码可以参考 http://aospxref.com/android-12.0.0_r3/

这篇文章主要讨论的是点击桌面图标之后,activity 启动的流程图。

参考博客: 慢~再听我讲一遍Activity的启动流程 Activity启动流程?基于Api30的Activity启动流程分析 android线程管理五(ActivityThread与ApplicationThread) Android Launcher 启动 APP 流程的源码分析 Android12 应用启动流程分析

流程图

启动流程源码比较复杂,为了更好的理解主要流程,先梳理流程图如下(参考第一篇博客)。 更详细的流程图(参考第二篇博客)。

启动流程

只关注里面的核心流程,至于一些细节,可以后面慢慢完善补充。

第一阶段(Launcher 向 AMS 发送启动请求)

Activity.java 这里的 startActivity 是从 Launcher 这个 activity 的 startActivitySafely 调用过来的,调用到 startActivity. 方法的重载 startActivity startActivityForResult, 这里 requestCode 参数用于 onActivityResult 的回调使用,开发者可以指定这个参数,当这个参数为负数时候,没有实际作用。 继续重载 startActivityForResult 方法,此时将会走到 Instrumentation 这个类,调用 execStartActivity 这个方法。 这个方法传递了七个参数,其中,mMainThread, 代表 Launcher 应用程序的主线程;mMainThread.getApplicationThread() 获取到的是 ActivityThread 的内部类 ApplicationThread, 代表 Launcher 应用进程的 IBinder 接口,之后 AMS 通过这个对象和 App (指 Launcher)通信;mToken 代表 Launcher activity 的 IBinder 接口。

这里的 mParent 参数,可能是代表了这个 activity 的父 activity, 这个参数在 attach 的时候被赋值,可以关注一下 Instrumentation.java

每个 activity 都持有 Instrumentation 对象,通过它的 execStartActivity 函数来继续完成启动 Activity 的流程。

参考这个类的注释,可以发现这个类主要是用于实现应用程序检测代码的基类,当打开检测运行的时候,这个类将在任何程序代码之前为您实例化,从而允许您监控系统和应用程序之间的所有交互过程。 execStartActivity, 首先会测试下是否和 ActivityMonitor 匹配,之后才会调用到 ActivityTaskManagerService 来执行 startActivity execStartActivity, 关注下传参: who, 这个 activity 是被谁启动的; token, 启动这个 activity 的 token; target, 是哪个 activity 执行的启动; intent, requestCode 和 options 没有变化;

第二阶段(AMS 启动 Activity, 并告知 Launcher pasue)

ActivityTaskManagerService.java

ActivityTaskManagerService 是一个系统服务,用于管理 activity 和他们的 containers,比如 task, display.

startActivity startActivityAsUser, 方法重载 ActivityStartController.java

这个类是委派 activity 启动的控制器,真正的启动也是由 ActivityStarter 来实现的。 obtainStarter,这里使用到了工厂模式,并且对 ActivityStarter 进行了配置(前面 startActivityAsUser 的一系列 set)。 ActivityStarter

ActivityStarter 类是真正的控制一个 activity 是怎么启动的类,这个类收集了所有用于决定如何将intent和标志转换为一个活动以及关联的任务和根任务的逻辑。 execute,这个方法是 actvity 启动起始,先只关注它的核心的部分

executeRequest,这个方法会做一些基本的检查,流程会从 startActivityUnchecked 走到 startActivityInner, 先只关注他的核心部分 这个方法会构造出来 ActivityRecord 的实例,一个 ActivityRecord 对应一个 Activity,但是一个 Activity 可能对应多个 ActivityRecord,因为可能会多次启动。 startActivityUnchecked, 这里会先 deferWindowLayout,finally 方法里面还有 continueWindowLayout,理由是 startActivityInner 可能会失败 startActivityInner 在 startActivityInner 方法中,存在有两个比较核心的部分:

mTargetRootTask.startActivityLocked() 判断当前 activity 是否可见,以及是否需要为其新建 task, 并根据不同的情况将 ActivityRecord 加入到对应的 task 栈顶中;

mRootWindowContainer.resumeFocusedTopActivities() 将所有聚焦的 task 的所有 activity 恢复运行,因为有些刚加入的 activity 是出于暂停状态的。

……(这部分流程不太清楚,很多和窗口相关的内容,后续梳理!)

后续会调用到 startSpecificActivity,并且判断目标 activity 所在应用是否正在运行,如果在运行,就会继续调用到 realStartActivityLocked() ,如果没有在运行,则会首先通过 mService.startProcessAsync() 来启动进程。

第三阶段 (App 进程的 Activity 启动流程)

这一阶段的启动主要是依靠 ClientTransaction 来进行

/* ActivityStackSupervisor.java realStartActivityLocked() */ ...... final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken); ...... // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(isTransitionForward); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // schedule transaction. mService.getLifecycleManager.scheduleTransaction(clientTransaction); ......

通过一系列的调用,最终会通过 TransactionExecutor 来执行

/* frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java */ public void execute(ClientTransaction transaction) { ...... executeCallbacks(transaction); executeLifecycleState(transaction); ...... }

这里的会有两处的 execute: executeCallbacks: 此处对应上面添加的 LaunchActivityItem,启动相关的内容都在这里,会回调到比较熟悉的 onCreate 方法; executeLifecycleState: 此处对应上面添加的 ResumeActivityItem,resume 相关的内容都在这里,会回调到比较熟悉的 onResume 方法;

总结

还有很多需要整理的地方,继续完善!


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #APP #启动流程与 #Activity #启动流程梳理 #Android #12 #启动流程梳理学习中