第三篇:SystemServer——Android 框架层的大脑

如果说 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

scss 复制代码
// 文件: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

伪代码:反射启动服务流程

typescript 复制代码
// 文件: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(预编译优化)。
csharp 复制代码
// 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 状态流转

scss 复制代码
// 文件: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 上。

原理:

  1. MessageQueue:一个阻塞队列,存放待处理的消息(如启动 App、广播、Binder 请求回调)。
  2. Looper.loop() :无限循环,从队列取消息。
  3. Handler:分发消息到具体的处理函数。

为什么不用多线程?

  • 避免锁竞争:系统服务内部状态极其复杂(如 AMS 的进程表、PMS 的包列表)。单线程模型避免了复杂的同步锁(synchronized),保证了数据一致性。
  • Binder 线程池:虽然主线程是单线程,但 Binder 请求由专门的线程池处理,处理完后通过 Handler 抛回主线程执行逻辑。
ini 复制代码
// 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 硬件功能扩展,非核心路径

关键技术点回顾:

  1. 反射加载 :SystemServiceManager 动态实例化服务。
  2. 状态机 :AMS 通过 mSystemReady 标志位控制系统可用状态。
  3. IPC 交互 :PMS 通过 Socket 与 vold 交互进行 Dex 优化。
  4. 单线程模型:依靠 Looper + Binder 线程池实现高效并发。

下篇预告

SystemServer 已经就绪,AMS 发出了 ACTION_BOOT_COMPLETED 广播。

接下来,Launcher(桌面) 启动了,你看到了熟悉的图标。

当你点击一个图标时:

  • AMS 如何决定启动哪个进程?
  • Binder 如何在 AMS、App 进程和 Zygote 之间穿梭?
  • Activity 的生命周期(onCreate -> onStart -> onResume)究竟是谁在回调?

下篇我们将追踪一次完整的 App 启动流程,深入 Binder 通信与 Activity 生命周期管理的腹地。
敬请期待:《从点击到显示:App 启动与 Activity 生命周期的全景追踪》

相关推荐
蒸鱼Yuzheng1 小时前
Android 构建可复现性:APK 指纹、文件级差异与供应链审计
android·apk·devops·软件供应链·可复现构建
墨天梦3 小时前
D03_Compose列表与稳定身份
android·gitee·kotlin
萌新杰少4 小时前
Kuikly股票查看软件开发体验——SaiRen
android·kotlin·客户端
vilya4 小时前
把 Python 塞进 APK:Chaquopy 打包实践
android·python
用户92817267390164 小时前
Android Compose版本的AI组件库来了。
android·kotlin
知昂七昂4 小时前
00-02:AOSP 源码阅读环境与检索方法论源码剖析(Android 16 / aosp-main)
android
知昂七昂4 小时前
00-01:AOSP 源码仓库结构与 repo 工作流源码剖析(Android 16 / aosp-main)
android·google
跨境数据猎手4 小时前
Android Native 层黑盒调用实战:unidbg 模拟执行 so 的原理
android
镜象科技5 小时前
中小学AI心理健康解决方案服务商怎么选?2026年选型参考
android·java·人工智能
脚踏实地,坚持不懈!6 小时前
从 AOSP 源码角度分析 Android 定位性能问题
android