SystemServer 概述与启动流程
SystemServer 是什么?说白了,它就是 Android 系统的「大管家」。所有你听过的核心服务 —— ActivityManagerService、WindowManagerService、PackageManagerService —— 全都运行在这个进程里。嗯,这个进程是在 Zygote 之后第二个被启动的 Java 层进程,它一旦挂掉,整个系统就黑屏重启,所以它也是整个系统的压舱石。
核心指标:SystemServer 进程在 Android 10 以后稳定占用约 80~150 个线程,堆内存起始分配 8MB,后期根据服务数量动态增长到 200MB 以上。
1.1 启动时机与入口
系统上电后,init 进程解析 init.rc 启动 Zygote,Zygote 在 ZygoteInit.main() 中做完预加载后,会调用 forkSystemServer() 创建子进程。我刚开始学这部分时,一直好奇为什么要在 Zygote 里 fork —— 后来才知道,这是为了利用写时拷贝技术,让 SystemServer 直接继承 Zygote 已经加载好的 Java 框架和资源,省去重复预加载的时间。
1.2 启动流程拆解
从 Zygote 到 SystemServer 跑起来,大致经历以下阶段。我个人习惯把流程记成「一 fork、二 main、三线程、四服务」:
- Zygote 创建子进程:
ZygoteInit.forkSystemServer()执行系统调用 fork,并设置进程名 system_server。 - 执行 SystemServer.main():子进程从
com.android.server.SystemServer.main()进入。 - 初始化 Looper 和 Binder 线程池:
Looper.prepareMainLooper()+BinderInternal.setBlockedThreadCount()等。 - 启动系统服务管理框架:创建
SystemServiceManager,后者负责统一注册、启动和生命周期回调。 - 分阶段启动服务:按照引导服务、核心服务、其他服务的顺序依次初始化,每启动一个就会往 ServiceManager 中注册。
1.3 各类服务启动阶段
SystemServer 里服务的启动顺序是有严格讲究的。我曾经踩过坑:早期版本里 PackageManagerService 和 ActivityManagerService 的启动顺序调整过,导致某些设备开机后黑屏。下面这张表格把服务分类和启动时机列清楚:
| 服务阶段 | 典型服务 | 启动时机 | 作用简述 |
|---|---|---|---|
| 引导服务 | Installer, DeviceIdentifiersPolicyService, Cellular | 第 0 批(最先) | 提供底层支撑,如包安装、设备标识 |
| 核心服务 | ActivityManagerService, PackageManagerService, PowerManagerService | 第 1 批 | 管理应用、权限、电源 |
| 其他服务 | WindowManagerService, NotificationManagerService, AlarmManagerService | 第 2 批及以后 | 界面、通知、闹钟等上层功能 |
技巧:如果你需要在 SystemServer 里添加自定义服务,务必把启动代码放在 startOtherServices() 方法里,不要插到引导服务阶段,否则可能因为依赖未备齐而崩溃。
1.4 启动进程关系图
我把整个体系画成一张流程图,方便你跟踪进程和服务的启动路径。注意看那个红色的 Watchdog 节点 —— 我之前遇到过因为 SystemServer 卡死在 onStart() 回调里,Watchdog 迟迟没超时(因为没写对时间),结果整整过了 5 分钟才触发重启。嗯,从那以后我每次写新服务都会先调调 Watchdog。下面这张 SVG 清晰地展示了从 Zygote 到各个服务启动的全貌,我特别标出了常见触发埋点的位置。
1.5 埋点时机与关键点
为什么要关注启动流程?因为我们做初始化埋点,本质就是在这条链路的关键节点上插入 trace 或日志。我个人建议在以下几个位置打点:
- SystemServer.main() 入口:记录进程已经创建,时间戳清零。
- 每个服务 onStart() 回调前后:记录单个服务的启动耗时。我曾经用这种方式发现某个厂商的定制服务卡在
onBootPhase()里 2 秒多。 - Watchdog 触发前:如果某个阶段超时,需要立即 dump 当前线程堆栈——但不是所有团队都记得加这段。
注意:SystemServer 的启动时间直接影响开机速度。Android 官方推荐整体启动时间控制在 30 秒以内(从内核计时起),但很多低端机甚至要 1 分钟。如果埋点发现某个服务超过 3 秒还没启动完,就要警惕了。
嗯,关于 SystemServer 的启动流程就先聊到这里。记住这个流程,我们后面做埋点的时候,会在这些节点上逐次插入统计代码,最终形成一个完整的开机性能看板。