Android 进阶——解密笔记 (1),分享一些行业经验
[](
)1. init 进程启动过程
开机键引导芯片从 ROM 加载 BootLoader 到 RAM。
引导 BootLoader 拉起 Android OS。
Linux 内核启动,执行 init.cpp 的 main 函数,创建 init 进程。
init 进程中创建和挂载启动所需的文件目录,初始化属性服务、启动属性服务、解析 init.rc 配置文件并启动 Zygote 进程。
[](
)2. Zygote 进程启动过程
Zygote 进程
Android 系统中 DVM(Dalvik 虚拟机)和 ART、应用程序进程以及系统关键服务的 SystemServer 进程都是由 Zygote 创建的。
Zygote(孵化器)是通过 fork(复制)进程的形式来创建应用程序进程以及 SystemServer,同时 Zygote 进程在启动的时候会 fork Dalvik/ART
所以由 Zygote 创建的进程都拥有一个独立的 DVM/ART 虚拟机的实例副本。这也是为什么 Android 中应用程序是独立、安全、稳定的,不会因为一个进程出现错误导致所有进程被 Kill。
Zygote 进程启动
创建 AppRuntime 调用 start 方法,启动 Zygote 进程。
创建 Java 虚拟机并为虚拟机注册 JNI 方法。
通过 JNI 方法调用 ZygoteInit.java 的 main 函数进入 Zygote 的 Java 框架层。
预加载类和资源,并启动 SystemServer。
通过 registerZygoteSocket 方法创建服务器端的 Socket,并通过 runSelectLoop 方法等待 AMS 的请求来创建新的应用程序进程。
时序图:
[](
)3. SystemServer 进程启动过程
SystemServer 进程
SystemServer 进程主要用于创建系统服务,例如 AMS、WMS、和 PMS 都是由它来创建的。
Service 进程启动
启动 Binde 线程池,这样就可以与其他进程进行通信。
创建 SystemServiceManager,用于对系统的服务进行创建、启动生命周期管理。
启动各种系统服务(引导服务、核心服务、其他服务)。
时序图
[](
)4. Launcher 启动过程
Launcher
当系统启动到最后一步时,会启动一个应用程序,也就是我们通常看到的应用桌面,它被称作 Launcher,在 Launcher 程序启动的时候会请求 PackageManagerService 来获取当前系统已安装的应用程序,并将其应用信息封装成快捷方式展现在我们的屏幕桌面上,这样用户通过点击应用图标就可以启动应用程序了。
所以 Launcher 由两个特点:
作为 Android 系统的启动器,用于启动应用程序。
作为 Android 系统的桌面,用于显示和管理应用程序的快捷图标或其他桌面组件。
时序图
[](
)总结:Android 系统启动流程
启动电源以及系统启动。(引导芯片从固化在 ROM 的预定义地方执行,加载主引导 BootLoader 到 RAM)
引导程序 BootLoader。(把系统 OS 拉起来)
Linux 内核启动。(设置缓存、被保护存储器、计划列表、加载驱动。内核完成时,首先在系统文件中寻找 init.rc 文件,并启动 init 进程)
init 进程启动。(初始化和启动属性服务,并启动 Zygote 进程)
Zygote 进程启动。(创建 Java 虚拟机并为 Java 虚拟机注册 JNI 方法,创建服务端 Socket,启动 SystemServer 进程。)
SystemServer 进程启动。(启动 Binder 线程池和 SystemServiceManager,并且启动各种系统服务。)
Launcher 启动。(被 SystemServer 进程启动的 AMS 会启动 Launcher,Launcher 启动后会将已安装的应用程序快捷方式图标展示到桌面。)
图示:
[](
)应用程序启动过程
如果启动一个应用程序,AMS 会检测该应用程序进程是否存在,如果不存在则向 Zygote 进行请求创建。
我们知道 Zygote 的 Java 框架层中创建了一个服务端的 Socekt,用于等待 AMS 创建新的应用进程请求。AMS 发起请求后,Zygote 会 fock 自身进程来创建应用程序,这样应用程序进程在启动时就拥有了虚拟机实例,同时也创建了 Binder 线程池和消息循环,这样运行在应用程序进程中的应用程序就可以进行进程间通信以及消息处理了。
[](
)1. AMS 发送启动应用进程请求时序图
[](
)2. Zygote 接收请求并创建应用程序进程时序图
我们看到该时序图和上文提到的 SystemServer 启动过程时序图有相似之处。共同点都是从 ZygoteInit 调用 RuntimeInit 的 applicationInit 开始,后续执行流程一样。
注:为什么 Android 会选择抛出 MethodArgsCall 异常的方式来调用方法而不是直接调用 SystemService 的 main 方法或 ActivityThread 的 main 方法?
是因为抛出异常的处理会清除所有的设置过程需要的堆栈帧(内存优化)
[](
)3.消息循环创建过程
ActivityThread 是用于管理当前应用程序进程的主线程。其部分关键源码如下:
public static void main(String[] args){
...
// 创建主线程 Looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if(sMainThreadHandler == null){
// 创建主线程 H 类
sMainThreadHandler = thread.getHandler();
}
if(false){
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Looper 开始工作
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
评论