2. AMS 启动流程:SystemServer启动、AMS实例化、关键初始化步骤

大家好,我是你们的老朋友。今天我们来聊聊 AMS 的启动流程。说实话,这块内容我当年啃源码的时候也绕了不少弯路。你想想看,Android 系统启动时,那么多服务要初始化,AMS 作为核心中的核心,它的启动时机和步骤就显得格外重要。

我个人习惯把 AMS 的启动分成三个阶段来看:SystemServer 的启动AMS 的实例化、以及关键初始化步骤。咱们一个一个来拆解。

2.1 SystemServer 启动:一切的起点

Android 系统启动后,Zygote 进程会 fork 出 SystemServer 进程。SystemServer 是 Android Framework 的“大管家”,几乎所有系统服务都在这里创建。

我记得第一次看 SystemServer 的 main 方法时,发现它其实就做了三件事:

  1. 初始化系统上下文(SystemContext)
  2. 创建 SystemServiceManager
  3. 启动各种服务

说白了,SystemServer 就是一个巨大的启动脚本。它按照优先级顺序,把一个个服务“拎”起来。AMS 就是其中最重要的一个。

关键点:SystemServer 启动时,会先启动一些“引导服务”(Bootstrap Services),比如 Installer、DeviceIdentifiersPolicyService,然后才是 AMS 这样的“核心服务”(Core Services)。

2.2 AMS 实例化:从 startBootstrapServices 到 startCoreServices

AMS 的实例化发生在 SystemServer 的 startBootstrapServices() 方法中。嗯,这里要注意,虽然 AMS 是核心服务,但它其实是在引导阶段就创建的。

我们来看一下关键的代码调用链:

// SystemServer.java
private void startBootstrapServices() {
    // ... 其他引导服务 ...
    
    // 实例化 AMS
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class);
    
    // ... 其他操作 ...
}

// SystemServiceManager.java
public <T extends SystemService> T startService(Class<T> serviceClass) {
    // 通过反射创建服务实例
    Constructor<T> constructor = serviceClass.getConstructor(Context.class);
    T service = constructor.newInstance(mContext);
    
    // 调用服务的 onStart 方法
    service.onStart();
    
    return service;
}

这里有个设计模式的小技巧——Lifecycle 模式。AMS 本身不直接继承 SystemService,而是通过一个内部类 Lifecycle 来包装。这样做的好处是,AMS 可以保持自己的继承体系,同时又能够被 SystemServiceManager 统一管理。

我的经验:我在项目中遇到过类似的设计需求。当时需要把一个已有的服务类接入到 SystemService 的管理框架中,但又不想破坏它的继承结构。Lifecycle 模式就是最好的解决方案。说白了,就是加一层“适配器”。

2.3 关键初始化步骤:AMS 的“成人礼”

AMS 实例化之后,还需要经过一系列初始化步骤才能真正“上岗”。我把它总结为四个关键步骤:

步骤 方法 主要工作
1. 构造函数初始化 ActivityManagerService() 创建 Handler、线程池、数据目录等
2. 系统就绪 systemReady() 恢复上次关机时的 Activity 栈、启动 Home 应用
3. 启动桌面 startHomeActivityLocked() 启动 Launcher 应用
4. 发布服务 publishBinderService() 将 AMS 注册为系统服务,供其他进程调用

咱们重点说说 systemReady() 这个方法。你想想看,AMS 启动后,系统可能之前非正常关机过,有些 Activity 还停留在栈里。AMS 需要把这些状态恢复过来。

我曾经在调试一个开机崩溃的问题时,发现就是 systemReady() 中恢复 Activity 栈时出了异常。当时排查了很久,最后发现是某个第三方应用的 Activity 在序列化时出了问题。

避坑指南:我曾经遇到过一个问题:AMS 在 systemReady() 阶段如果耗时过长,会导致系统启动动画卡住。这是因为 systemReady() 是在主线程执行的。所以,Google 在后续版本中把一些耗时操作移到了子线程。

2.4 整体流程可视化

为了让大家更直观地理解,我画了一张流程图。这张图展示了从 SystemServer 启动到 AMS 完全就绪的完整路径。

AMS 启动流程总览 Zygote 进程 SystemServer.main() startBootstrapServices() AMS.Lifecycle 实例化 systemReady() → 启动桌面 fork 子进程 创建系统上下文 引导服务阶段 反射创建 AMS 恢复状态 & 启动

2.5 初始化中的几个关键细节

除了上面说的流程,还有几个细节我觉得值得提一下:

  • Handler 线程:AMS 内部有一个名为 mHandler 的 Handler,它运行在一个名为 android.fg 的线程上。这个线程负责处理大部分 AMS 的内部消息。
  • Activity 栈的初始化:AMS 在构造函数中会创建 mStackSupervisor,它是 Activity 栈的管理器。所有的 Activity 启动、切换、销毁都由它协调。
  • Broadcast 队列:AMS 会初始化两个广播队列——前台队列和后台队列。前台队列的超时时间是 10 秒,后台是 60 秒。

核心总结:AMS 的启动流程,说白了就是 SystemServer 在引导阶段通过反射创建 AMS 实例,然后调用 systemReady() 恢复系统状态,最后启动桌面应用。整个过程环环相扣,任何一个环节出问题,都可能导致系统无法正常启动。

好了,关于 AMS 的启动流程就讲到这里。下一章我们会深入 AMS 的内部数据结构,看看它是如何管理 Activity 栈的。嗯,这部分内容会更贴近实际开发,敬请期待。


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