2. AMS 启动流程:SystemServer启动、AMS实例化、关键初始化步骤
大家好,我是你们的老朋友。今天我们来聊聊 AMS 的启动流程。说实话,这块内容我当年啃源码的时候也绕了不少弯路。你想想看,Android 系统启动时,那么多服务要初始化,AMS 作为核心中的核心,它的启动时机和步骤就显得格外重要。
我个人习惯把 AMS 的启动分成三个阶段来看:SystemServer 的启动、AMS 的实例化、以及关键初始化步骤。咱们一个一个来拆解。
2.1 SystemServer 启动:一切的起点
Android 系统启动后,Zygote 进程会 fork 出 SystemServer 进程。SystemServer 是 Android Framework 的“大管家”,几乎所有系统服务都在这里创建。
我记得第一次看 SystemServer 的 main 方法时,发现它其实就做了三件事:
- 初始化系统上下文(SystemContext)
- 创建 SystemServiceManager
- 启动各种服务
说白了,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 完全就绪的完整路径。
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 栈的。嗯,这部分内容会更贴近实际开发,敬请期待。