前面追到 system_server 的出生点:Zygote fork 出子进程,子分支完成 specialize,最后进入 com.android.server.SystemServer.main()。
这时容易出现两种相反的误解:
"它刚出生,所以里面什么都没有";
"它继承了 Zygote,所以系统服务已经都在里面了"。
两种说法都把"运行环境"和"系统服务"混成了一层。
进入
SystemServer.main()时,system_server 已是拥有 ART、Framework JNI、预加载页面和 Binder IPC 基础设施的独立进程;但 System Context、主 Looper 的长期循环、SystemServiceManager 以及 AMS/PMS/WMS 等服务仍要由SystemServer.run()组织建立。
本篇只回答"一个可运行的子进程怎样搭好服务容器骨架"。服务怎样从构造走到 ready,留给下一篇。
源码基线: Android 16 QPR2
android-16.0.0_r4,frameworks/basecommit45034f0663f960d9ee5fb0a101a4732b71f6e2f4。
一、进入 main 的那一刻,已经有什么?
到达 Java 入口前,子进程已经走过:
lua
Zygote preload
→ fork
→ system_server specialize
→ 完成通用 child 初始化
→ 进入 SystemServer.main()
Binder 线程池的完整 child 调用链已在 第五篇给出;本篇只讨论它与主 Looper 的职责区别。
于是"出生清单"可以分成两列:
| 已经具备 | 仍未建立 |
|---|---|
| 独立 PID、system UID/GID/capability 与 SELinux 身份 | System Context / System UI Context |
| ART、Framework JNI 与 fork 后运行时状态 | system_server 主线程的长期 Looper 循环 |
| Zygote 预加载的类、资源和库页面 | SystemServiceManager |
| Binder IPC 线程池 | AMS、PMS、WMS 等服务对象及其发布状态 |
因此,system_server 不是"空地址空间",却仍是一个尚未完成 Framework 服务装配的容器。
二、SystemServer.main() 只是装配入口
typescript
public static void main(String[] args) {
new SystemServer().run();
}
这里没有创建新进程。当前代码已经运行在 Zygote fork 出来的 system_server 中,只是创建一个 Java SystemServer 对象并调用 run()。
四个名字必须分开:
| 名称 | 类型 | 角色 |
|---|---|---|
system_server |
Linux 进程 | 承载大量 Framework 核心系统服务 |
SystemServer |
Java 类/对象 | 组织这个进程的初始化与服务启动 |
SystemServiceManager |
Java 管理对象 | 启动并分发一部分 SystemService 生命周期 |
SystemService |
Java 抽象基类 | 一类具有统一生命周期回调的服务实现 |
SystemServer 不是 AMS,也不是发布给 ServiceManager 的 Binder Service。它更像一次性的装配总控:把进程规则、Context、管理对象和服务启动顺序接起来,最后让主线程进入长期消息循环。
三、SystemServer.run() 要补齐哪几类设施?

不要把 SystemServer.run() 看成一串互不相干的初始化。它做的工作可以按目的归为四层:
markdown
1. 进程规则
调整 runtime、Binder、SQLite、Parcel、调度与安全相关策略
2. 执行基础设施
准备主 Looper,启动允许并行的初始化线程池
3. Framework 运行上下文
加载 android_servers,建立 System Context / System UI Context
4. 服务容器
创建 SystemServiceManager,随后开始分组启动系统服务
这个顺序有因果关系:服务构造需要 Context;统一生命周期需要 Manager;可能阻塞的远端调用和长期主线程则需要提前配置进程规则。
run() 末尾的 Looper.loop() 也不是"启动完成标志"。它表示主线程从一次性装配控制流进入长期事件循环,服务和用户级启动工作仍会继续发生。
四、system_server 中至少有三套执行路径
理解服务容器,不能只画对象,还要知道代码可能在哪条线程执行。
1. Java 主线程 / 主 Looper
SystemServer.run() 在当前启动线程调用:
ini
Looper.prepareMainLooper();
服务启动的大顺序由这条主控制流组织;末尾进入 Looper.loop() 后,它继续处理投递到 system_server 主 Looper 的消息。下一篇会进一步区分两件事:SystemService 文档要求生命周期方法由主 Looper 调用,但一次回调在实机上究竟落到哪条线程,仍由 SystemServiceManager 的实际调用点以及是否显式切线程决定。
2. Binder 线程
进入 Java main 前,system_server 已具备 Binder IPC 线程池;SystemServer.run() 还会配置线程数量与调度策略。此处重要的不是重复启动调用链,而是线程职责:
Binder 线程负责接收远端 transaction。它们不是主线程,也不会天然服从主 Looper 的消息顺序。服务若要把 IPC 工作转到主线程或自己的 HandlerThread,必须显式投递。
3. 初始化线程池与服务自有线程
SystemServerInitThreadPool 允许少量明确可并行的初始化任务与主线重叠。各服务启动后还可能创建自己的 HandlerThread、executor 或 Native 工作线程。
所以准确模型是:
SystemServer 主线程控制总体装配顺序;明确提交的初始化任务可以并行,Binder transaction 与服务内部后台工作又属于其他执行路径。
这一区分很重要:一个 Binder 线程阻塞,不自动等于 SystemServer 主启动线程卡死;反过来,主线程卡在服务启动,也不能靠观察某个 Binder 线程活跃来证明启动仍在推进。
五、为什么先要 System Context,再要 SystemServiceManager?
1. System Context:让服务获得 Framework 运行环境
createSystemContext() 的核心是:
ini
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
这里没有启动普通 Activity。ActivityThread 也不只服务于三方 App;systemMain() 为 system_server 建立资源、包与 Context 运行环境,使后续服务能够获得系统资源、ContentResolver 等基础能力。
System Context 不是"所有服务都 ready"的证明。它是后续服务构造和运行所依赖的容器环境。
2. SystemServiceManager:让部分服务共享生命周期框架
System Context 建立后,run() 创建:
ini
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
此时它只是 system_server 进程内的 Java 对象和 LocalServices 条目,不是独立进程,也不是面向 App 的 Binder 接口。
它出现是因为接下来需要统一完成几件事:
scss
以 System Context 构造 SystemService;
记录由它启动的服务实例;
调用 onStart();
保存当前 Boot Phase;
向已纳管服务分发生命周期回调。
它不会读取全局依赖图自动拓扑排序,也不管理 system_server 中的每一种服务形态。显式顺序与 ready 机制是下一篇的主线。
六、什么时候才真正开始创建服务?
容器骨架建立以后,run() 才进入服务装配:
scss
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
startApexServices(t);
这些名称首先是 SystemServer.java 的源码分组与大体顺序,不是四个 Boot Phase,也不对应 init rc 的 class_start core。
服务的启动形态也并不统一:
scss
mSystemServiceManager.startService(SomeLifecycle.class)
SomeLegacyService.main(...)
ServiceManager.addService(name, binder)
对象构造后再显式调用 systemReady()
因此,"开始调用 startBootstrapServices()"只能说明服务创建阶段已经开始,不能说明所有 Bootstrap 服务已完成,更不能说明 Framework 已 ready。
Watchdog 会在 bootstrap 早期启动,以便尽早发现启动死锁;system_server_dumper 也会较早发布,给调试构建提供内部状态入口。这些设施很重要,但在本篇只需知道它们位于容器基础设施与早期服务装配之间,不需要抢占主线。
容器已经搭好,为什么能力仍不能立即使用?
到这里,system_server 已经从"可运行的 Zygote 子进程"变成"能够开始承载 Framework 服务的容器":
sql
有独立进程身份
→ 有 ART 与 Binder 基础设施
→ 有主 Looper 与初始化执行路径
→ 有 System Context
→ 有 SystemServiceManager
→ 开始创建服务
但"开始创建"与"服务可用"之间仍有一段关键距离:构造函数、onStart()、Binder/LocalService 发布、Boot Phase、服务专用 systemReady() 与异步初始化分别代表什么?下一篇专门拆开这些里程碑。
源码定位
SystemServer.main()/run():system_server 总装配入口。createSystemContext():ActivityThread.systemMain()与 System Context。startBootstrapServices():早期服务与 Watchdog。