Android启动

Android 架构

4u54y

Android 启动

Android 系统启动流程分 4 部分:

iuy62

init 进程启动

  1. 启动电源,加载引导程序到 RAM,开始执行
  2. 执行引导程序 bootloader

bootloader 是 Android 系统开始运行前的一个小程序,主要是将 OS 拉起来,它不是 AndroidOS 的一部分。

  1. Kernel 启动

当 Kernel 完成系统设置时,它首先在系统文件中寻找 init.rc 文件,并启动 init 进程

  1. init 进程启动

init 进程主要是用来初始化和启动属性服务,并启动 Zygote 进程。
init 进程是用户进程,是所有用户进程的鼻祖,pid=1。

Zygote 进程启动

Zygote 理解?

Zygote,译为受精卵,是 Android 启动过程中第一个 Java 进程的名称。

Zygote 进程作用

Zygote 进程是 init 进程启动创建的,又称孵化器,它的作用:

Zygote 进程在启动的时候会创建虚拟机 (Dalvik 或 ART),因此通过其 fork 而创建的应用程序或 SystemServer 进程可以在内部获取一个虚拟机实例的副本。

Zygote 进程会启动虚拟机,加载一些系统资源,这些都是 system_server 进程和应用进程所需要的,Zygote 是这两者的一个抽象。
所有应用程序在启动时共性操作?
共性操作可以放到 zygote 中去提前处理,最大的共性便是启动运行时。其中会预先加载一些 boot class,这些类使用频繁,因此在 Zygote 中提前加载好,可以极大地提升后续应用的启动速度

Zygote 进程启动流程

init.rc→init 进程→fork+execve 系统调用→Zygote

init 进程会根据 rc 文件执行一系列启动操作,其中有一项就是启动 Zygote 进程,init 会 fork 出一个子进程,然后再通过 exec 加载 /system/bin/app_process 可执行文件

然后,zygote 便会将自身挂起,等待来自于 system_server 进程启动的请求。

Zygote Native 世界

  1. 启动 Android 虚拟机
  2. 注册 Android 的 JNI 函数
  3. 进入到 Java 世界:创建 Android 虚拟机实例,并调用 ZygoteInit 的 main 方法 (JNI 调用)

从这里开始从 Native 进入到 Java 层,可以认为 Zygote 开创了 Java Framework。

Zygote Java 世界

  1. 通过 ZygoteServer socket 监听 AMS 请求 Zygote 来创建新的应用程序进程
  2. 通过 forkSystemServer() fork 出 SystemServer 进程

注意

  1. Zygote fork 要单线程
  2. Zygote 多线程 fork 可能会死锁,Zygote 为了避免这个问题,在 fork 的时候把其它线程都给停掉了
  3. Zygote 的 IPC 没有采用 Binder,而是采用的 LocalSocket

SystemServer 进程启动

SystemServer 进程作用?

SystemServer 进程是 Zygote 进程 fork 的第一个 Java 进程。
SystemServer 进程主要是用来创建系统服务的。

SystemServer 启动

3h0hg

Launcher 的启动

Activity 的冷启动流程

见:AMS#点击一个 APP 到 View 呈现中间发生了什么?

面试题

应用是如何启动 Binder 机制的?

应用天生就支持 binder 机制,在进程创建的时候会创建 binder 线程池,

孵化应用进程为什么不交给 SystemServer 来做,而是专门设计一个 Zygote?

应用启动时候需要做很多准备工作,包括启动虚拟机、加载各类系统资源,是非常耗时的。
应用进程在启动时候,内存空间除了必要的资源外,最好是干干净净的,不要继承一堆乱七八糟的东西。
所以给 SystemServer 进程和应用进程都要用到的资源抽出来单独放在一个进程里,这就是 Zygote 进程,再由 Zygote 进程分别 fork 出 SystemServer 进程和应用进程,孵化后它们就可以各干各的事了。

Zygote 的 IPC 通信机制为什么不采用 Binder?采用 Binder 会有什么问题?