Activity启动流程

Activity启动流程

https://mp.weixin.qq.com/s/1bfi-BVe23_96A2AlhaPKg

系统启动触发Launcher流程

系统开机时加载引导程序并初始化各个硬件,初始化完成后会创建出第一个用户进程 Init进程(pid=1),随后孵化出 adbd(adb 命令)logd(日志输出) 两个守护进程,执行完成之后还会孵化出第一个 java 进程,也就是 Zygote 进程,它会调用 ZygoteInit.java 这个类,在这个类的入口方法会创建 Framework SystemServer 系统服务进程,即 SystemServer.java 这个类,在这个 SystemServer 这个类里面又会创建我们熟知的系统服务:ActivityManagerServiceWindowManagerServicePowerManagerServiceInputManagerService 等等,同时创建出 binder 线程池,当所有服务启动完毕后,就会调用 ActivityManagerService.systemReady() 来启动 Launcher 应用了。

Launcher 启动 App 流程

  • Launcher 监听到点击app事件,调用 Activity.startActivityForResult() ,转到 Instrumentation 类的 execStartActivity 方法
  • Instrumentation 通过跨进程通信告诉 ATMS 要启动应用的需求
  • ATMS 反馈 Launcher 让其进入 Paused 状态
  • 随后 ATMS 转到 ZygoteProcess 类,通过 socketZygote 通信,告知 Zygote 需要新建进程
  • Zygote fork 进程,并调用 ActivityThreadmain 方法,也就是app的入口
  • ActivityThread 创建 ActivityThread 实例,新建 Looper 实例,开始 loop 循环
  • 同时 ActivityThread 告知 AMS,进程创建完毕,开始反射创建 Application Provider,并调用 Applicationattach onCreate 的方法
  • 最后创建上下文,反射创建 Activity,开始调用生命周期

问题

  1. ActivityManagerServiceActivityTaskManagerService 的区别?
    • 原本四大组件的通信都是 AMS 来处理,后期 AMS 过于臃肿,将 Activity 相关工作转移到 ATMS
  2. 怎么判断应用进程存在?
    • 如果进程存在,ATMS 里面会保存有 WindowProcessController 信息,这个信息包括 processNameuiduid 则是应用程序的 id,可以通过 applicationInfo.uid 获取。所以判断进程是否存在,根据 processNameuid 去判断是否有对应的 WindowProcessController,并且 WindowProcessController 里面的线程不为空。
  3. 怎么创建进程,为什么要通过 socket 进行 IPC 通信而不是 binder?
    • 通过 socketZygote 进行通信,然后 Zygote 进行 fork 进程并返回新进程的 pid
    • fork() 方法是类 Unix 操作系统上创建进程的主要方法,用于创建当前进程的副本
    • 因为 binder 是多线程交互,而 fork 不允许存在多线程,原因是会出现死锁,例如主进程里的A线程持有锁后,fork 出的子进程同样将锁 fork 出来了,当子进程的线程需要用到该锁,那么就会出现死锁

ZygoteInit.java 里做的业务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static main(String argv[]) {
// 1. 预加载 frameworks/base/preloaded-classes 和 framework_res.apk 等系统资源
// 应用在启动时需要大量调用系统资源,这里预先调用可以提高应用响应速度
preloadClasses();
preloadResources();
preloadSharedLibraries();

// 2. 启动 system_server 进程。该进程是 framework 核心
if(argv[1].equals("start-system-server")) {
startSystemServer();
}

// 3. 创建 Socket 服务
registerZygoteSocket();

// 4. 进入阻塞状态,等待连接,用以处理来自 AMS 申请进程创建的请求
runSelectLoopMode();
}

SystemServer.java 里做的业务:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String argv[]) {
// 创建系统服务管理者
SystemServiceManager mSystemServiceManager = new SystemServiceManager(mSystemContext);
// 启动引导服务
startBootstrapServices(t);
// 启动核心服务
startCoreServices(t);
// 启动其它一般服务
startOtherServices(t);
// 当所有服务启动完毕会调用ActivityManagerService.systemReady来启动launcher应用
mActivityManagerService.systemReady()
}

Launcher 启动流程示意

相关成员:

  • ActivityRecordServerActivity 的映射,存放了 Activity 的各种信息,当 Activity 被回收时,临时保存的数据也会通过 Instrumentation.callActivityOnSaveInstanceState 跨进程通信保存在该类中
  • TaskRecord:单个任务栈记录
  • ActivityStackActivity 的栈管理,出栈入栈顺序等信息
  • ActivityStackSupervisor:管理各个app的任务栈管理者

【重点】留意 ActivityStarter,里面有检查配置清单里的信息,如果要处理插件化,Activity 配置清单信息要如何处理同让需要参考该类并hook里面的逻辑

Activity创建流程示意