1. AMS 与 WMS 核心架构:AMS 核心类图、WMS 窗口管理栈、关键数据结构
1.1 章节概述
本章从 Android Framework 最核心的两个系统服务——ActivityManagerService (AMS) 和 WindowManagerService (WMS) 出发,剖析它们在进程管理、Activity 生命周期调度、窗口层级合成与事件分发中的基石性地位。理解本章的类图与数据结构是后续所有调优、调试与稳定性修复的必备基础。
学习目标:
- 掌握 AMS 核心类图(ActivityRecord、TaskRecord、ProcessRecord、ActivityStack)的职责与关系。
- 掌握 WMS 窗口管理栈(RootWindowContainer -> DisplayContent -> WindowState)的分层逻辑。
- 熟悉 AMS 与 WMS 之间通过 Binder 和 SurfaceFlinger 协作的关键数据流。
1.2 AMS 核心类图深度拆解
1.2.1 关键数据结构列表
| 数据结构 | 存储内容 | 核心作用 |
|---|---|---|
| mActivities (ArrayMap<IBinder, ActivityRecord>) | 所有已注册的 ActivityRecord 实例 | 根据 Binder 快速查找 Activity |
| mTaskRecords (ArrayList<TaskRecord>) | 所有任务栈(Task)记录 | 管理前台/后台任务切换、affinity 匹配 |
| mProcessNames (ProcessMap<ProcessRecord>) | 按 (processName, userId) 索引的进程 | AMS 进程调度与 oom_adj 调整的直接依据 |
| mBackStack / mFocusedStack (ActivityStack) | 后台栈列表、前台焦点栈 | 智能 Activity 启动模式决策 |
调优视角:
ProcessRecord.oom_adj是 LMK (Low Memory Killer) 的关键权重,AMS 在updateOomAdjLocked()中动态调整。- ActivityRecord 内部的
appToken与 WMS 的IApplicationToken一一对应,跨服务交互时以此为凭据。
1.2.2 AMS 与 ActivityStack 的启动调度
启动一个 Activity 时,AMS 通过 startActivityLocked() 执行以下流程:
- 根据 Intent 解析目标 ActivityRecord(若无则创建)。
- 查找或创建 TaskRecord(由 launchMode、flags 决定)。
- 将 ActivityRecord 压入 ActivityStack(前台/后台/新栈)。
- 通过
realStartActivityLocked()通知对应 ProcessRecord 创建 ActivityThread。
// 关键代码路径:ActivityStack.java (Android 13+)
// 启动 Activity 时压栈操作
boolean startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition, ...) {
if (newTask) {
// 创建新 TaskRecord 并压入栈顶
TaskRecord task = new TaskRecord(mService, ...);
task.addActivityToTop(r);
mTaskHistory.add(task);
} else {
// 添加到现有 TaskRecord 的顶部
task.addActivityToTop(r);
}
// 更新焦点 ActivityRecord
mFocusedActivity = r;
}
1.3 WMS 窗口管理栈分层逻辑
1.3.1 窗口层级结构
WMS 维护一棵 窗口树,从 RootWindowContainer 向下逐层细分:
- RootWindowContainer:单例顶层容器,内部持有所有 DisplayContent 列表。
- DisplayContent:每个物理或虚拟显示设备对应一个,管理该屏下的所有 WindowToken 和 WindowState 层级。
- WindowToken:根据 分组的窗口集合(一个 Activity 通常对应一个 AppWindowToken)。
- WindowState:实际窗口实例,记录窗口坐标、Z-order、状态、SurfaceControl 句柄。
1.3.2 Z-order 与图层合成
WMS 通过以下规则决定窗口的 Z-order:
- 窗口类型(TYPE_APPLICATION, TYPE_SYSTEM_OVERLAY 等)。
- Activity 焦点状态、最近一次用户交互时间。
- 同 内子窗口的请求顺序。
// 简化自 WindowManagerService.assignLayersLocked()
// 分配 Z-order 的核心思路
private void assignLayersLocked(DisplayContent displayContent) {
int baseLayer = 0;
for (WindowState w : displayContent.getWindowList()) {
// 根据窗口类型和子窗口逻辑计算 layer
w.mLayer = baseLayer + w.mAttrs.type * 1000 + w.mSubLayer;
baseLayer++;
}
// 通知 SurfaceFlinger 调整 Layer 顺序
displayContent.getPendingTransaction()
.setLayer(w.mSurfaceControl, w.mLayer);
}
常见陷阱:
- AMS 与 WMS 间存在跨进程 Binder 调用,ActivityRecord 的 传递若失效会导致 窗口添加超时 ANR。
- WMS 窗口层设置错误(如 TYPE_SYSTEM_OVERLAY 滥用)可能导致触摸事件或导航栏遮挡。
- 在多屏 (DisplayContent > 1) 或分屏场景下,窗口 Z-order 需要跨 Display 独立分配,调优时需关注
displayId的隔离。
1.4 AMS ↔ WMS 数据流与关键 API
1.4.1 典型交互流程:Activity 启动窗口
| 步骤 | 调用方 | 被调用方 | 关键 API / 数据结构 |
|---|---|---|---|
| 1 | App (ActivityThread) | AMS | IApplicationThread.scheduleLaunchActivity() |
| 2 | AMS | WMS | IWindowManager.addWindow(…, appToken, …) |
| 3 | WMS | SurfaceFlinger | WindowState.mSurfaceControl → createSurface() |
| 4 | WMS | AMS | onWindowAdded(, displayId) |
1.4.2 关键数据结构之间的关系
ActivityRecord.appToken(Binder 对象)和IApplicationToken.asBinder()是 AMS 与 WMS 之间的“握手凭证”。WindowState.mToken指向对应的AppWindowToken,该 的appToken再映射回 AMS 侧的 ActivityRecord。ProcessRecord.thread(IApplicationThread)是 AMS 回调 App 能力的通道。
本章总结:
- AMS 核心数据结构 ActivityRecord / TaskRecord / ProcessRecord / ActivityStack 构成 Android 应用生命周期的底盘。
- WMS 窗口树 RootWindowContainer → DisplayContent → WindowToken → WindowState 决定着窗口的可见性、图层顺序以及 SurfaceFlinger 合成。
- 两套系统服务通过 Binder (IWindowManager / IApplicationThread) 和 机制紧密协作,形成一个完整的 Activity 窗口生命周期循环。
掌握本章中的类图与数据结构,是后续学习 AMS 启动速度调优、WMS 窗口合成效率优化、ANR 根因定位的必备前置技能。