第2章 Android系统启动
沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程
第2章 Android系统启动
本课程对应刘望舒《Android进阶解密》,电子工业出版社2018年10月初版,468页、702千字,ISBN 9787121348389。原书以Android 8.0系统源码为主;本页不会用Android 10后的ATMS、现代ART实现、Perfetto或新隐藏API政策替换原书链路。
沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程。源码实验固定AOSP Android 8.0与作者出版仓库提交 3860d9e1;后续版本只作为迁移差异,不改变正式目录分母。
学习目标
- 能解释“第2章 Android系统启动”全部正式目录节点,并定位Android 8.0中的入口类、函数与源码路径。
- 能绘制进程、线程、Binder/JNI/加载边界和关键状态转移,区分请求发出与系统完成。
- 能设计单变量故障实验,验证“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”。
- 能写出包含版本、源码、日志/追踪、反例、停止、恢复、回退和复核人的独立交接记录。
从一条可证伪的调用链开始
先预测:把启动描述成线性函数列表会忽略init action/service触发、Zygote socket、SystemServer服务依赖与Launcher查询包信息的跨进程边界。把预测写成入口、对象身份、进程/线程、状态和完成回调五列,再去读源码。若结果与预测不同,先修正模型,不要选择性截取调用栈。
原书面向应用开发者学习系统源码,重点不是抄完整函数,而是抓住跨层调用的关键节点。每个节点都要回答:谁发起、在哪个进程和线程执行、哪份状态被修改、后续如何被唤醒、失败如何返回、什么现象代表真正完成。
验收不变量是:每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成。只有源码版本、符号关系、运行轨迹与最终状态四类证据一致,结论才可以进入下一章。
核心词汇与版本门
↡init是本页第1个源码概念,必须同时说明Android 8.0定义、调用者、进程线程、状态、失败反例与证据、↡init.rc是本页第2个源码概念,必须同时说明Android 8.0定义、调用者、进程线程、状态、失败反例与证据、↡Zygote是本页第3个源码概念,必须同时说明Android 8.0定义、调用者、进程线程、状态、失败反例与证据、↡SystemServer是本页第4个源码概念,必须同时说明Android 8.0定义、调用者、进程线程、状态、失败反例与证据、↡Launcher是本页第5个源码概念,必须同时说明Android 8.0定义、调用者、进程线程、状态、失败反例与证据
以上词汇都固定在Android 8.0语义。Android 7.0只在原书明确比较AMS家族时出现;Android 9以后反射/隐藏API限制、Android 10的ActivityTaskManager、现代Profiler/Perfetto等只能写进迁移备注,不能改写本页正式链路。
原书目录逐节点重构
2.1 init进程启动过程
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
本节采用“入口 -> 关键对象 -> 状态转移 -> 跨进程/Native边界 -> 完成回调”的五列追踪法。保持Android 8.0镜像、样例和操作不变,只改变一个进程、线程、加载顺序或资源压力变量,避免把相关性误写成因果。
2.1.1 引入init进程
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.1.2 init进程的入口函数
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.1.3 解析init.rc
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.1.4 解析Service类型语句
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.1.5 init启动Zygote
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.1.6 属性服务
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.1.7 init进程启动总结
沿kernel_init进入PID 1,区分rc解析出的Action与Service,记录属性触发、fork/exec、重启策略和服务状态。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.2 Zygote进程启动过程
追踪app_process进入ZygoteInit、预加载、创建socket、接收参数和fork父子分支,明确SystemServer与普通应用的不同入口。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
本节采用“入口 -> 关键对象 -> 状态转移 -> 跨进程/Native边界 -> 完成回调”的五列追踪法。保持Android 8.0镜像、样例和操作不变,只改变一个进程、线程、加载顺序或资源压力变量,避免把相关性误写成因果。
2.2.1 Zygote概述
追踪app_process进入ZygoteInit、预加载、创建socket、接收参数和fork父子分支,明确SystemServer与普通应用的不同入口。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.2.2 Zygote启动脚本
追踪app_process进入ZygoteInit、预加载、创建socket、接收参数和fork父子分支,明确SystemServer与普通应用的不同入口。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.2.3 Zygote进程启动过程介绍
追踪app_process进入ZygoteInit、预加载、创建socket、接收参数和fork父子分支,明确SystemServer与普通应用的不同入口。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.2.4 Zygote进程启动总结
追踪app_process进入ZygoteInit、预加载、创建socket、接收参数和fork父子分支,明确SystemServer与普通应用的不同入口。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.3 SystemServer处理过程
从Zygote子进程进入SystemServer.main,按启动阶段记录AMS、PMS、WMS等服务的创建、注册和依赖就绪。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
本节采用“入口 -> 关键对象 -> 状态转移 -> 跨进程/Native边界 -> 完成回调”的五列追踪法。保持Android 8.0镜像、样例和操作不变,只改变一个进程、线程、加载顺序或资源压力变量,避免把相关性误写成因果。
2.3.1 Zygote处理SystemServer进程
追踪app_process进入ZygoteInit、预加载、创建socket、接收参数和fork父子分支,明确SystemServer与普通应用的不同入口。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.3.2 解析SystemServer进程
从Zygote子进程进入SystemServer.main,按启动阶段记录AMS、PMS、WMS等服务的创建、注册和依赖就绪。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.3.3 SystemServer进程总结
从Zygote子进程进入SystemServer.main,按启动阶段记录AMS、PMS、WMS等服务的创建、注册和依赖就绪。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.4 Launcher启动过程
追踪AMS选择Home、启动Launcher及Launcher通过PackageManager查询可启动Activity并构造图标模型的过程。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
本节采用“入口 -> 关键对象 -> 状态转移 -> 跨进程/Native边界 -> 完成回调”的五列追踪法。保持Android 8.0镜像、样例和操作不变,只改变一个进程、线程、加载顺序或资源压力变量,避免把相关性误写成因果。
2.4.1 Launcher概述
追踪AMS选择Home、启动Launcher及Launcher通过PackageManager查询可启动Activity并构造图标模型的过程。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.4.2 Launcher启动过程介绍
追踪AMS选择Home、启动Launcher及Launcher通过PackageManager查询可启动Activity并构造图标模型的过程。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.4.3 Launcher中应用图标显示过程
追踪AMS选择Home、启动Launcher及Launcher通过PackageManager查询可启动Activity并构造图标模型的过程。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
源码核查: 记录版本、文件/符号、进程、线程、输入、状态变化、返回或回调;若只有概念图而没有一条运行证据,本节点不通过。
2.5 Android系统启动流程
把“Android系统启动流程”放回沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程的主链,明确入口、关键状态、跨进程或跨层边界与完成点。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
本节采用“入口 -> 关键对象 -> 状态转移 -> 跨进程/Native边界 -> 完成回调”的五列追踪法。保持Android 8.0镜像、样例和操作不变,只改变一个进程、线程、加载顺序或资源压力变量,避免把相关性误写成因果。
2.6 本章小结
把“本章小结”放回沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程的主链,明确入口、关键状态、跨进程或跨层边界与完成点。 阅读时先预测正常轨迹,再只注入一个失败变量,并以“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”核验源码、日志和最终状态。
本节采用“入口 -> 关键对象 -> 状态转移 -> 跨进程/Native边界 -> 完成回调”的五列追踪法。保持Android 8.0镜像、样例和操作不变,只改变一个进程、线程、加载顺序或资源压力变量,避免把相关性误写成因果。
本页完整节点清单
本页承担23个目录或复习节点,正文、图解、实验和题目必须能反向定位每一项:
- 2.1 init进程启动过程
- 2.1.1 引入init进程
- 2.1.2 init进程的入口函数
- 2.1.3 解析init.rc
- 2.1.4 解析Service类型语句
- 2.1.5 init启动Zygote
- 2.1.6 属性服务
- 2.1.7 init进程启动总结
- 2.2 Zygote进程启动过程
- 2.2.1 Zygote概述
- 2.2.2 Zygote启动脚本
- 2.2.3 Zygote进程启动过程介绍
- 2.2.4 Zygote进程启动总结
- 2.3 SystemServer处理过程
- 2.3.1 Zygote处理SystemServer进程
- 2.3.2 解析SystemServer进程
- 2.3.3 SystemServer进程总结
- 2.4 Launcher启动过程
- 2.4.1 Launcher概述
- 2.4.2 Launcher启动过程介绍
- 2.4.3 Launcher中应用图标显示过程
- 2.5 Android系统启动流程
- 2.6 本章小结
分步追踪:源码、运行与反例
定位源码入口与责任边界
固定Android 8.0标签,从公开入口向下追踪,不跳过Binder代理、JNI注册、ClassLoader查找或system_server状态对象。
可复现实验
kernel -> init(PID 1) -> app_process -> Zygote -> system_server -> Launcheron boot -> class core -> service zygote -> socket zygote -> startadb shell ps -A | grep -E 'zygote|system_server|launcher'
adb shell getprop sys.boot_completed动手试:在同一镜像、同一构建和同一输入上重复正常、冷启动/首次加载、热路径、单变量失败与恢复五轮。记录PID/TID、调用入口、对象或token、状态前后值、耗时、异常/返回码和最终可见结果;性能章再记录P50/P95/P99,内存章保留GC Root路径。
独立证据门
最小证据包包含:出版社目录、Android版本、源码文件和符号、调用/状态图、PID/TID或加载器身份、一条失败注入、日志/追踪/堆证据、最终结果、已知限制、停止、恢复、回退、责任人与复核人。
练习
练习
问题 1:为什么“第2章 Android系统启动”必须固定Android 8.0?
问题 2:怎样构造“把启动描述成线性函数列表会忽略init action/service触发、Zygote socket、SystemServer服务依赖与Launcher查询包信息的跨进程边界”的最小反例?
问题 3:何时可以认为本页完成独立交接?
本章回顾
“第2章 Android系统启动”的核心是沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程。把启动描述成线性函数列表会忽略init action/service触发、Zygote socket、SystemServer服务依赖与Launcher查询包信息的跨进程边界是必须保留的反证;源码阅读只有连接运行时的进程、线程、状态与最终结果,才从“知道类名”升级为“能诊断”。
名词解释
本章出现的专业名词,用大白话再讲一遍。
- init
init服务于“沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程”。掌握标准是能定位Android 8.0源码、画出运行轨迹、构造单变量反例,并用“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”独立验收。
- init.rc
init.rc服务于“沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程”。掌握标准是能定位Android 8.0源码、画出运行轨迹、构造单变量反例,并用“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”独立验收。
- Zygote
Zygote服务于“沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程”。掌握标准是能定位Android 8.0源码、画出运行轨迹、构造单变量反例,并用“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”独立验收。
- SystemServer
SystemServer服务于“沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程”。掌握标准是能定位Android 8.0源码、画出运行轨迹、构造单变量反例,并用“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”独立验收。
- Launcher
Launcher服务于“沿init、Zygote、SystemServer和Launcher四段主链追踪Android 8.0从PID 1到应用图标可见的启动过程”。掌握标准是能定位Android 8.0源码、画出运行轨迹、构造单变量反例,并用“每个阶段都明确谁创建下一进程、使用何种配置或IPC、何时进入消息循环,以及何种日志证明阶段完成”独立验收。