如果说 Zygote 是孕育生命的“母体”,那么 SystemServer 就是 Android 系统的“大脑”。
它由 Zygote 孵化而来(PID 仅次于 Zygote),却承载着整个 Android 框架层的核心逻辑。没有它,手机只是一块能亮屏的砖头;有了它,App 才能被管理、窗口才能被绘制、权限才能被校验。
本篇我们将深入 frameworks/base/services/java/com/android/server/SystemServer.java,拆解这颗“大脑”是如何一步步苏醒,并注册 AMS(活动管家)和 PMS(应用管家)这两大核心神经中枢的。
第一步:SystemServer 的觉醒 —— main 函数
Zygote 通过 forkSystemServer 创建了这个进程。入口依然是 Java 的 main 方法。
代码位置:frameworks/base/services/java/com/android/server/SystemServer.java
// 文件:frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
// 1. 初始化线程优先级 (SCHED_FIFO),确保系统服务响应最快
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
// 2. 设置 Binder 线程池上限 (默认 15 个)
BinderInternal.setMaxThreads(15);
// 3. 【关键】准备主线程 Looper
// SystemServer 是一个单线程模型(大部分逻辑),依赖 Looper 处理消息
prepareLooper();
// 4. 启动引导服务 (Bootstrap Services)
// 如:ActivityManagerService, PowerManagerService
startBootstrapServices();
// 5. 启动核心服务 (Core Services)
// 如:WindowManagerService, PackageManagerService
startCoreServices();
// 6. 启动其他服务 (Other Services)
// 如:BluetoothService, WifiService
startOtherServices();
// 7. 进入消息循环,永不停歇
Looper.loop();
}
硬件视角:此时 CPU 正在高优先级运行这个线程。
Binder线程池的创建意味着内核中为该进程分配了专门的线程来处理跨进程请求。
第二步:服务大管家 —— SystemServiceManager
SystemServer 不再手动 new 每一个服务,而是委托给 SystemServiceManager。它利用反射机制,根据配置动态加载服务。
代码位置:frameworks/base/services/java/com/android/server/SystemServer.java & SystemServiceManager.java
伪代码:反射启动服务流程
// 文件:frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public void startService(@NonNull final String serviceName) {
try {
// 1. 通过类名加载 Class 对象
Class<?> cl = Class.forName(serviceName);
// 2. 获取构造函数 (参数为 Context)
Constructor<?> constructor = cl.getConstructor(Context.class);
// 3. 实例化服务对象
Object service = constructor.newInstance(mContext);
// 4. 如果服务实现了 SystemService 接口,调用 onStart()
if (service instanceof SystemService) {
((SystemService) service).onStart();
}
// 5. 加入管理列表
mServices.add((SystemService) service);
} catch (Exception ex) {
throw new RuntimeException("Failed to start service " + serviceName, ex);
}
}
设计模式:这是典型的工厂模式 + 反射。Android 通过配置文件(如
com.android.server.SystemServer中的硬编码或 XML)决定启动哪些服务,解耦了启动逻辑与服务实现。
第三步:三大阶段启动时序图
SystemServer 的启动分为三个阶段,顺序严格,依赖关系明确。
流程图:SystemServer 启动时序
第四步:双核驱动 —— AMS 与 PMS 的爱恨情仇
AMS (ActivityManagerService) 和 PMS (PackageManagerService) 是系统最复杂的两个服务,它们互相依赖,启动顺序极其讲究。
1. PMS 的启动:应用的“户籍管理员”
代码位置:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- 阶段一(Bootstrap) :在
startBootstrapServices中启动,仅解析/system分区的关键 APK(如 framework.jar, settings.apk)。此时无法安装用户 App。 - 阶段二(Core) :在
startCoreServices中,扫描/data/app和/vendor,加载所有已安装应用的信息。 - 交互:PMS 需要调用 Installer 服务(通过 Socket 与底层
vold进程通信)来执行dexopt(预编译优化)。
// PMS 与 Installer 交互伪代码
mInstaller = new Installer(new ServiceConnection() {
public void onConnected() {
// 连接成功,可以执行 dexopt 或安装应用
mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, ...);
}
});
2. AMS 的启动:进程的“总指挥”
代码位置:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- 早期:在
startBootstrapServices中实例化,注册到ServiceManager。 - 等待:AMS 启动后会挂起,直到 PMS 扫描完成,因为它需要知道哪些 App 存在。
- SystemReady:当所有核心服务就绪,AMS 调用
systemReady(),标志着系统正式可用。
伪代码:AMS 状态流转
// 文件:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) return; // 防止重复调用
mSystemReady = true; // 状态标记:系统已就绪
// 1. 恢复持久化进程 (如 Launcher, InputMethod)
retrieveSettings();
startPersistentApps(PersistentIds.RESTART_ON_REBOOT);
// 2. 广播 ACTION_BOOT_COMPLETED
// 告诉所有 App:系统启动了,可以开始干活了
broadcastIntentInLock(..., Intent.ACTION_BOOT_COMPLETED);
// 3. 启动 Home 桌面
startHomeActivityLocked();
}
if (goingCallback != null) goingCallback.run();
}
第五步:Looper 机制 —— 单线程的高并发秘密
SystemServer 的主线程(以及 AMS/PMS 的主线程)都运行在 Looper 上。
原理:
- MessageQueue:一个阻塞队列,存放待处理的消息(如启动 App、广播、Binder 请求回调)。
- Looper.loop() :无限循环,从队列取消息。
- Handler:分发消息到具体的处理函数。
为什么不用多线程?
- 避免锁竞争:系统服务内部状态极其复杂(如 AMS 的进程表、PMS 的包列表)。单线程模型避免了复杂的同步锁(synchronized),保证了数据一致性。
- Binder 线程池:虽然主线程是单线程,但 Binder 请求由专门的线程池处理,处理完后通过 Handler 抛回主线程执行逻辑。
// Looper 循环简化版
while (true) {
Message msg = queue.next(); // 阻塞,直到有消息
if (msg == null) break;
msg.target.dispatchMessage(msg); // 调用 Handler 处理
msg.recycle();
}
本篇小结
| 服务类别 | 代表服务 | 启动阶段 | 核心职责 |
|---|---|---|---|
| 引导服务 | AMS, PMS (部分), PowerMgr | startBootstrapServices | 建立基础框架,互相依赖的最小集 |
| 核心服务 | WMS, PMS (完整), InputMgr | startCoreServices | 窗口管理、全量包扫描、输入事件 |
| 其他服务 | Wifi, Bluetooth, Battery | startOtherServices | 硬件功能扩展,非核心路径 |
关键技术点回顾:
- 反射加载:
SystemServiceManager动态实例化服务。 - 状态机:AMS 通过
mSystemReady标志位控制系统可用状态。 - IPC 交互:PMS 通过 Socket 与
vold交互进行 Dex 优化。 - 单线程模型:依靠 Looper + Binder 线程池实现高效并发。
下篇预告
SystemServer 已经就绪,AMS 发出了 ACTION_BOOT_COMPLETED 广播。
接下来,Launcher(桌面) 启动了,你看到了熟悉的图标。
当你点击一个图标时:
- AMS 如何决定启动哪个进程?
- Binder 如何在 AMS、App 进程和 Zygote 之间穿梭?
- Activity 的生命周期(onCreate -> onStart -> onResume)究竟是谁在回调?
下篇我们将追踪一次完整的 App 启动流程,深入 Binder 通信与 Activity 生命周期管理的腹地。
敬请期待:《从点击到显示:App 启动与 Activity 生命周期的全景追踪》