4、SystemServer的初始化阶段:Phase0到Phase100的启动阶段划分、各阶段加载的核心服务
好,咱们今天来聊聊SystemServer的启动阶段。说实话,这个知识点我当年啃源码的时候,绕了不少弯路。SystemServer不是一口气把所有服务都启动起来的,它分了几个阶段,每个阶段都有明确的任务。我习惯把这几个阶段叫做Phase0到Phase100,虽然源码里不是这么命名的,但这样理解起来更直观。
4.1 为什么要有阶段划分?
你想想看,Android系统启动时,硬件刚初始化完,很多基础设施还没准备好。如果一上来就把所有服务都加载,肯定会出问题。比如,你想启动一个需要网络的服务,但网络模块还没初始化,这不就崩了吗?
所以,SystemServer采用了分阶段启动的策略。说白了,就是先搭好地基,再盖楼。每个阶段只加载那些依赖已经满足的服务。我在项目中遇到过几次因为服务启动顺序不对导致的死锁问题,后来发现就是阶段划分没理解透。
4.2 Phase0:基础环境准备
这是SystemServer的入口阶段。我记得第一次看这段代码时,感觉特别琐碎,但其实每一行都很关键。
核心任务:设置系统属性、初始化Binder线程池、加载JNI库。
具体来说,Phase0做了这几件事:
- 设置时区与语言环境——从系统属性中读取,确保后续服务能正确获取本地化信息。
- 初始化Binder线程池——SystemServer本身也是一个Binder服务,需要提前准备好通信能力。
- 加载libandroid_servers.so——这个JNI库包含了大量native层的服务实现。
嗯,这里要注意:Phase0不启动任何具体的系统服务,它只是把运行环境搭好。我曾经犯过一个错误,想在Phase0里直接调用某个服务,结果发现Binder还没准备好,直接抛了异常。
4.3 Phase1:核心基础设施服务
到了Phase1,开始加载第一批服务了。这些服务是后续所有服务的依赖基础。我个人习惯把Phase1叫做“骨架阶段”,因为搭起来的是整个系统的骨架。
| 服务名称 | 作用 | 启动顺序 |
|---|---|---|
| PowerManagerService | 电源管理,控制屏幕亮灭、休眠唤醒 | 第1个 |
| ActivityManagerService | 四大组件的管理核心 | 第2个 |
| PackageManagerService | 应用安装、卸载、权限管理 | 第3个 |
| DisplayManagerService | 显示设备管理 | 第4个 |
为什么PowerManagerService要第一个启动?因为其他服务在初始化时可能需要申请唤醒锁,没有电源管理,这些操作就没法做。我记得有一次调试一个低功耗问题,发现某个服务在Phase1启动时申请了唤醒锁但没释放,结果系统一直无法休眠。排查了半天,才发现是启动顺序导致的依赖问题。
避坑指南:我曾经在Phase1里尝试启动一个需要网络的服务,结果发现ConnectivityService还没初始化。记住,Phase1只加载最核心的基础服务,网络相关的要等到后面。
4.4 Phase2:系统服务扩展
Phase2开始加载一些“业务型”服务了。这些服务依赖Phase1的基础设施,但本身又是上层应用的基础。我把它叫做“血肉阶段”。
这个阶段加载的服务包括:
- WindowManagerService——窗口管理,负责界面布局和输入事件分发。
- InputManagerService——输入事件处理,触摸、按键都归它管。
- ContentService——内容提供者管理,跨进程数据共享的基础。
- NotificationManagerService——通知管理,状态栏通知的幕后功臣。
你可能会问,为什么WindowManagerService不放在Phase1?因为WMS需要依赖DisplayManagerService和PowerManagerService,而这些在Phase1才刚启动完。说白了,Phase2的服务都是“消费者”,它们要等Phase1的“生产者”准备好才能工作。
4.5 Phase3:网络与连接服务
到了Phase3,网络相关的服务开始登场。这个阶段我特别关注,因为网络问题是最难排查的之一。
核心服务:ConnectivityService、WifiService、BluetoothService、TelephonyRegistry。
ConnectivityService是网络状态管理的核心,它负责监听网络变化、切换网络类型。WifiService和BluetoothService则分别管理无线连接。TelephonyRegistry负责电话状态的注册与通知。
嗯,这里有个细节:TelephonyRegistry虽然叫“电话”,但它其实只是一个状态注册中心,真正的电话功能由TelephonyManager在应用层实现。我刚开始看源码时,以为TelephonyRegistry就是打电话的,结果发现完全不是一回事。
4.6 Phase4:媒体与图形服务
Phase4加载的是媒体和图形相关的服务。这些服务对性能要求很高,所以放在比较靠后的阶段,确保前面的基础设施已经稳定运行。
| 服务名称 | 作用 |
|---|---|
| MediaRouterService | 媒体路由管理 |
| AudioService | 音频策略管理 |
| CameraService | 相机服务(native层) |
AudioService是个很有意思的服务。它不直接管理音频硬件,而是负责音频策略——比如哪个应用可以播放声音、音量怎么调节。真正的音频数据流由AudioFlinger在native层处理。我调试过一个音频焦点冲突的问题,两个应用同时播放音乐,结果AudioService的优先级策略没生效,最后发现是服务启动时注册监听器的顺序有问题。
4.7 Phase5到Phase100:收尾与优化
从Phase5开始,加载的服务越来越“外围”。比如:
- Phase5:LocationManagerService(定位服务)、SearchManagerService(搜索服务)。
- Phase6:WallpaperManagerService(壁纸服务)、DreamManagerService(屏保服务)。
- Phase7及以后:各种系统UI服务、辅助功能服务等。
到了Phase100,其实就是SystemServer启动的最后一个阶段——系统就绪通知。这时会调用ActivityManagerService.systemReady(),通知所有已注册的服务:系统已经准备好了,你们可以开始干活了。
注意:Phase100不是真的100个阶段,而是一个形象的说法。实际上SystemServer的启动阶段在源码里是用枚举或常量定义的,大概有10个左右。我习惯用Phase0到Phase100来表示从开始到结束的完整过程。
4.8 总结一下
SystemServer的启动阶段,说白了就是一个依赖链的构建过程。每个阶段只加载那些依赖已经满足的服务,确保系统稳定启动。我个人建议你在阅读源码时,重点关注每个服务的onStart()方法和systemReady()回调,这两个地方最能体现服务的启动时机和依赖关系。
我曾经在优化系统启动速度时,尝试调整过几个服务的启动顺序。结果发现,有些服务虽然看起来没有直接依赖,但底层共享了同一个锁资源,调整顺序后反而导致了死锁。所以,不要轻易改动启动顺序,除非你完全理解了每个服务的依赖关系。
好,这一章就到这里。下一章咱们会深入分析ActivityManagerService的启动细节,看看AMS是怎么管理四大组件的。到时候再聊。