背景
Android 应用的启动过程是一个绕不开的问题, 不但对于我们开发有帮助, 而且从操作系统的角度看问题, 提高我们的技术视野.
第一个阶段: 系统启动
1. 首先是 Android 系统启动.
这时候第一进程是 zygote.zygote 英文是受精软的意思 (一查吓一跳). 为啥是受精软呢? 因为系统的所有进程都是由 zygote 进程 fork 而来. zygote 最先启动的第一个进程是鼎鼎大名的 SystemServer 进程. 这个进程包含了我们常说的三个大神级系统服务, 分别是 ActivityManagerService,WindowManagerService 以及 PackegeManagerService.
2. 紧接着是我们的所在应用的进程启动.
进程入口在 ActivityThread 这个类的 main() 方法, 这个 main 方法类似 C 语言的 mian 方法, 是一个程序入口. main 方法做了以下几件事: <1 初始化我们的 mainLopper 和 mainHander, 这样 UI 线程消息机制就开启了. <2 调用 ActivityThread 的 attach() 方法.
第二个阶段: app 注册
3.ActivityThread 的 attach() 方法
这个方法会接着调用 ActivityManagerNatvie(一个单例类, 可以获取 ActivityManagerService 的实例) 的 getDeafault() 返回 ActivityManagerService 实例, 接着调用 ActivityManagerService.attachApplication(mAPPThread) 方法. 这个 mAPPThread 是 ApplicationThread 的实例.
ApplicationThread
ApplicationThread 是 ActivityThread 的内部类, 他是 App 和系统跨进程交互的入口, 它的实现类在客户端进程, SystemServer 的 AMS 通过 ApplicationThread 的实例来和 App 进程通信, 包括生命周期的回调. ApplicationThread 在 App 进程的实现类通过 H 这个 handler 和 ActivityThread 跨线程交互, 完成生命周期的最终回调, 这些时间类型是诸如: LAUNCH_ACTIVITY 和 RESUME_ACTIVITY 以及 Servivce 的生命周期也是 H 这个 Handler 处理的, 这个叫做 H 的 Handler 是 UI 线程.
Servivce 为什么是在 UI 线程?
这个问题上一段已经回答, 因为生命周期的回调的 H 这个 Handler 是在 UI 线程.
4.ActivityManagerService.attachApplication(mAPPThread) 方法
补充一下: 系统看来, 其实也就是 AMS 看来, 每个 App 都对应一个进程, 存储在 ProcessRecord 这个数据结构. app 的每个 Activity 都对用一个 ActivityRecord 这个数据结构, 每个 Activity 都对应一个 Token, 这个 Token 也是 Binder 对象, 用来唯一都应一个 Activity.
5. 调用 mAPPThread.bindApplication(ProcessRecord 等参数)
这是一个跨进程调用实际上把 App 信息同步到 ProcessRecord 方便系统管理.
6.ActivityStackSupervisor.attachApplicationLocked(ProcessRecord) 方法
这个类是一个 AMS 的一个栈管理类, 里面存储着 ActivityStack 的集合. 在这个方法, 会遍历各个 ActivityStack, 找到前台栈, 找到里面的 TopActivity. 然后比较 传进来的 ProcessRecord.processName 和 UID 是否个和 opActivity 对用的 ActivityRecord 里面的一致. 如果一致, 就调用 ActivityStackSupervisor.realStartAcvitiyLocked(ProcessRecord,ActivityRecord) 方法.
7.ActivityStackSupervisor.realStartAcvitiyLocked(ProcessRecord,ActivityRecord) 方法.
这个方法会调用传过来的 ApplicationThread 实例的 ScheduelLaunchActivity(包括 ActivityRecord) 方法.
第三个阶段: 启动第一个 Activity
8.ApplicationThread.ScheduelLaunchActivity(包括 ActivityRecord) 方法.
这个方法是跨进程的, 会把 ActivityRecord 同步到 App 进程的 ActivityRecordClient 数据结构, 用来后面构造 Application 和 Activity 等.
9. 发送给 H 一个 H.LAUNCH_ACTIVITY 的消息
10. 调用 ActivityThread 的 HandleLaunchActivity() 方法.
接着调用 PerformLaunchActivity 方法和 HandleLaunchActivtiy() 方法. #第四个阶段: 显示画面 这个阶段后续再详细讲, 这里就简单提一下.
PerformLaunchActivity 做的事
1. 这个方法主要是构造 Application 和通过 mInstrumention.newActivity() 构造 Activity. 2. 调用 Activity 的 attach(application 的 ContextImpl 等信息)
Activity 的 attach(application 的 ContextImpl 等信息)
这个方法会初始化一个 Window, 以后详细讲, 人格视图都是附在一个 window 的 docorView 上, 然后由 WMS.addView 显示.
HandleLaunchActivtiy
这个方法会调用 Actiity 的 resume() 方法, 并且在 makrVisible() 里面调用 WMS.addView(window), 这个 windows 里面的 docorView 的 contentView 就是 onCreate() 里面 setContentView(int layout) 设置的 contentView.
最后显示出来了
注意关于 WMS.addView(window), 这个系统服务, 我们下次再讲, 里面有一个类 RootViewImpl, 这个类负责管理我们 contentView 视图树的逐级绘制.
来源: https://juejin.im/post/5b3885d96fb9a00e687a0708