AMS 与 ATMS 的区别解析

自 Android 10 (API 29) 开始,Google 对原本庞大的 ActivityManagerService (AMS) 进行了结构性重构,将其核心的 Activity 管理职能抽离出来,成立了 ActivityTaskManagerService (ATMS)。

1. 为什么要进行拆分?

在早期的 Android 版本中,AMS 承载了太多的职责。这种“巨石”设计导致了严重的工程问题:

核心痛点 详细解析与举例
代码耦合严重 现象:Activity 栈管理逻辑与广播分发逻辑共用同一个线程/锁。
举例:在计算复杂的 Task 切换(如分屏模式下的 Activity 移动)时,如果逻辑出错产生死锁或耗时过长,会直接阻塞同一进程内的广播分发 Handler,导致无关的广播接收者出现 ANR。
职责不清晰 现象:WMS 需要频繁跨模块获取 Activity 状态。
举例:WMS 在准备窗口切换动画时,必须知道 Activity 是否可见。旧版 WMS 需通过繁琐的 IPC 调用 AMS 的 ActivityRecord 状态,这不仅产生了大量的跨模块冗余代码,还增加了同步状态时的延迟。拆分后,ATMS 与 WMS 深度融合,共同管理 WindowContainer 层级结构。
维护成本极高 现象:单文件行数爆炸,合并冲突不断。
举例ActivityManagerService.java 的源码量曾一度突破 30,000 行。开发者 A 在修复 Service 粘性启动的 Bug,开发者 B 在优化 Activity 的启动速度,由于两人都在操作同一个文件,导致每次版本合并时都会产生极其复杂的代码冲突。

核心管理对象:Record 体系

为了实现职责分离,AMS 与 ATMS 分别维护了不同的核心数据对象:

对象名称 所属服务 核心职责
ProcessRecord AMS 进程管家。描述一个应用进程的实体,记录了进程的 PID、UID、包含的组件(Service, Receiver)、进程优先级(Adj)以及内存状态。AMS 通过它来决定系统内存不足时该“杀掉”哪个进程。
ActivityRecord ATMS Activity 档案。描述一个 Activity 实例的最小单位。记录了 Intent、所属 Task、状态(Resumed, Paused 等)、对应的 WindowToken。它与应用端的 Activity 实例一一对应。
TaskRecord ATMS 任务容器。描述一个“最近任务”或“任务栈”。管理一组相关的 ActivityRecord,决定了 Activity 的回退顺序(LIFO,后进先出)以及在多窗口模式下的显示分组。

2. AMS vs ATMS 职责对比

维度 ActivityManagerService (AMS) ActivityTaskManagerService (ATMS)
核心职责 管理应用生命周期(进程、四大组件中的后三者)。 专门管理 Activity 及其容器(Task, Stack, Display)。
组件管理 Service, BroadcastReceiver, ContentProvider。 Activity 启动、生命周期、Task 切换。
进程管理 负责 OOM Adjuster、进程启动与回收。 不直接参与进程管理。
交互对象 主要与 ProcessRecord 交互。 主要与 ActivityRecordTaskRecord 交互。
WMS 关系 间接交互。 强绑定。与 WMS 共同管理窗口 and Activity。

3. 架构演进的关键点

3.1 跨进程通信的变化

  • Android 9 以前:App -> AMS (startActivity)。
  • Android 10 以后:App -> ATMS (startActivity)。

3.2 内部协作流程

  1. ATMS 负责判断 Activity 应该在哪个 Task 启动,并管理其生命周期状态。
  2. 当需要启动一个新的进程来承载 Activity 时,ATMS 会回调 AMSstartProcessAsync 方法。
  3. AMS 负责与 Zygote 通信并完成进程的创建。

4. 总结:一句话区分

  • ATMS 是“Activity 管家”:只关心 Activity 怎么跳、怎么显示、怎么分组。
  • AMS 是“应用管家”:关心进程还在不在、Service 跑没跑、广播发没发。

这种拆分使得 Android 系统在支持 多窗口模式 (Multi-Window)折叠屏 (Foldables) 时,逻辑更加清晰和独立。

, ,