第六章 SystemServer进程:系统服务启动与注册

SystemServer,这个名字听起来就很有分量。它是Android系统的“大管家”,几乎所有你叫得上名字的系统服务——ActivityManagerService、WindowManagerService、PackageManagerService——都在这里启动和运行。今天我们就来聊聊这个进程是怎么启动的,以及那些核心服务是怎么注册和初始化的。

6.1 SystemServer的启动流程

还记得Zygote进程吗?它孵化了第一个Java进程——SystemServer。具体来说,Zygote在fork自身之后,会调用SystemServer的main方法。嗯,这里有个细节:Zygote启动SystemServer时,会通过反射调用com.android.server.SystemServer的main方法。

// 在ZygoteInit.java中
if (startSystemServer) {
    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
    if (r != null) {
        r.run();
        return;
    }
}

我刚开始看这段代码时,觉得挺简单的。但实际项目中,SystemServer的启动远比想象中复杂。它要加载各种库、初始化服务、注册到ServiceManager……每一步出错都可能导致系统无法正常启动。

SystemServer的main方法做了三件大事:

  1. 加载本地库(如android_servers)
  2. 创建SystemServer实例并调用run方法
  3. 在run方法中启动所有系统服务

说白了,run方法就是整个SystemServer的核心。它按照优先级顺序,依次启动引导服务、核心服务和其他服务。我习惯把run方法比作一场交响乐的指挥——每个服务就像不同的乐器,必须在正确的时机加入演奏。

关键点:SystemServer的启动顺序是严格定义的。引导服务(如Installer、DeviceIdentifiersPolicyService)最先启动,然后是核心服务(如AMS、WMS、PMS),最后是其他服务(如CameraService、MediaService)。

6.2 系统服务注册与管理(ServiceManager)

ServiceManager是什么?你可以把它想象成一个“服务黄页”。每个系统服务启动后,都要到ServiceManager这里注册自己的名字和Binder引用。其他进程想用某个服务时,先通过ServiceManager查询,拿到Binder引用后再调用。

你想想看,如果没有ServiceManager,每个服务都得自己暴露端口、自己处理连接请求,那得多乱?ServiceManager的存在,让服务发现变得简单而统一。

// 服务注册示例
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.ACTIVITY_SERVICE, am);

ServiceManager本身也是一个服务,但它比较特殊——它是在init进程中启动的,比SystemServer还早。我记得有一次排查问题,发现某个服务注册失败,导致系统一直重启。后来定位到是ServiceManager的Binder线程池满了,无法处理新的注册请求。嗯,这种问题在低端设备上更容易出现。

避坑指南:我曾经遇到过服务注册后无法被其他进程找到的情况。原因是服务注册时使用的名称与查询时使用的名称不一致——大小写差了一个字母。ServiceManager的键是大小写敏感的,这一点务必注意。

6.3 核心服务初始化

核心服务有三个:ActivityManagerService(AMS)、WindowManagerService(WMS)、PackageManagerService(PMS)。它们各自负责什么?简单来说:

  • AMS:管理Activity的生命周期、任务栈、进程调度
  • WMS:管理窗口的创建、布局、输入事件分发
  • PMS:管理应用的安装、卸载、权限、组件信息

这三个服务的初始化顺序是固定的:先PMS,再AMS,最后WMS。为什么?因为AMS需要PMS提供已安装应用的信息,WMS又需要AMS提供Activity的窗口状态。说白了,它们之间有依赖关系。

6.3.1 PackageManagerService的初始化

PMS的初始化是最耗时的。它要扫描所有已安装的应用,解析AndroidManifest.xml,构建包信息数据库。我见过一些低端手机首次开机要等很久,就是因为PMS在扫描大量预装应用。

// PMS初始化核心逻辑
public PackageManagerService(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    // 扫描系统应用
    scanDirLI(systemDir, ...);
    // 扫描非系统应用
    scanDirLI(vendorDir, ...);
    // 扫描data分区应用
    scanDirLI(dataDir, ...);
}

PMS初始化完成后,会通过ServiceManager注册自己。这样其他服务就能通过ServiceManager查询到PMS的Binder引用,进而调用它的方法。

6.3.2 ActivityManagerService的初始化

AMS的初始化相对复杂。它要创建系统进程的ActivityRecord、初始化任务栈、启动系统UI(如SystemUI)。我记得有一次,AMS初始化时因为SystemUI启动失败,导致整个系统卡在开机动画——嗯,这就是所谓的“死机”现象。

// AMS初始化核心逻辑
public ActivityManagerService(Context systemContext) {
    // 创建系统进程的ActivityRecord
    mSystemThread = ActivityThread.systemMain();
    // 初始化任务栈
    mStackSupervisor = new ActivityStackSupervisor(this);
    // 启动系统UI
    startSystemUi();
}

注意事项:AMS初始化时,会调用startSystemUi()启动SystemUI。如果SystemUI的apk损坏或签名不正确,AMS会抛出异常,导致SystemServer进程崩溃。我曾经在OTA升级后遇到过这个问题——新版本的SystemUI与旧版本的AMS不兼容。

6.3.3 WindowManagerService的初始化

WMS的初始化依赖于AMS。它需要AMS提供当前焦点Activity的信息,才能正确管理窗口的Z-order。WMS初始化时,会创建WindowManagerPolicy(策略类),用于处理窗口的显示策略(如状态栏、导航栏的显示与隐藏)。

// WMS初始化核心逻辑
public WindowManagerService(Context context, InputManagerService inputManager,
        boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
    // 创建窗口策略
    mPolicy = new PhoneWindowManager();
    // 初始化输入系统
    mInputManager = inputManager;
    // 创建窗口管理器
    mWindowMap = new HashMap<IBinder, WindowState>();
}

WMS初始化完成后,会注册到ServiceManager。这样,其他进程(如应用进程)就能通过ServiceManager获取WMS的Binder引用,进而创建窗口、调整窗口大小等。

6.4 知识体系总览

下面这张图展示了SystemServer进程的核心知识体系。你可以看到,从Zygote孵化开始,到SystemServer启动,再到三个核心服务的初始化与注册,整个流程环环相扣。

SystemServer进程知识体系 Zygote进程 SystemServer进程 ServiceManager 服务注册与管理 PMS 包管理服务 AMS Activity管理服务 WMS 窗口管理服务 依赖关系:PMS → AMS → WMS 所有服务通过ServiceManager注册,供其他进程调用

6.5 总结

SystemServer的启动流程,说白了就是“Zygote孵化 → 加载库 → 启动服务 → 注册到ServiceManager”。核心服务的初始化顺序是PMS → AMS → WMS,它们之间有明确的依赖关系。ServiceManager作为服务注册中心,是整个系统服务架构的基石。

我在实际项目中,经常遇到SystemServer启动慢或崩溃的问题。排查思路通常是:先看logcat中SystemServer的启动日志,定位到哪个服务初始化失败;然后检查该服务的依赖是否满足;最后看ServiceManager是否正常工作。嗯,这套方法屡试不爽。

个人建议:如果你刚开始学习SystemServer,不要试图一次性理解所有细节。先掌握启动流程和三个核心服务的职责,然后逐步深入每个服务的内部实现。我在带新人时,通常让他们先画一张SystemServer启动流程图,把每个阶段的关键代码标注出来——这个方法很有效。

公众号:蓝海资料掘金营,微信deep3321