第4章 AMS、WMS、PMS核心职责边界
Android 框架层(Framework Layer)的核心由三大系统服务组成:ActivityManagerService(AMS)、WindowManagerService(WMS)、PackageManagerService(PMS)。这三者共同构建了应用从安装、启动到界面呈现的完整生命通道。本章聚焦三者的职责边界、进程模型、数据流与信任链路,以及在实际架构演进中的选型权衡与落地风险。
4.1 三大服务的职责核心
AMS、WMS、PMS 分别对应应用生命周期管理、窗口显示管理和应用包信息管理三大正交领域。以下表格从 职责边界、进程模型、核心数据和关键流程四个维度进行对比。
| 维度 | AMS(ActivityManagerService) | WMS(WindowManagerService) | PMS(PackageManagerService) |
|---|---|---|---|
| 职责边界 | 管理 Activity/Service/Broadcast/ContentProvider 的生命周期、任务栈、进程优先级、权限检查 | 管理窗口层次、窗口大小/位置/动画、输入法窗口、屏幕旋转、多窗口/分屏 | 管理 APK 安装/卸载/更新、AndroidManifest 解析、权限声明、组件元数据、签名验证 |
| 进程模型 | 运行于 SystemServer 进程,通过 Binder 与应用进程通信 | 运行于 SystemServer 进程,通过 Binder 与 SurfaceFlinger、InputDispatcher 通信 | 运行于 SystemServer 进程,通过 Binder 与安装器(Installer)及应用进程通信 |
| 核心数据 | ActivityRecord/TaskRecord/ProcessRecord 栈、mServices、mRecentTasks | WindowState 树、DisplayContent 集合、WindowToken 映射 | PackageSetting、PackageParser 解析树、permissions 数据库 |
| 关键流程 | startActivity → 创建 ActivityRecord → 通知 WMS 增加窗口 → 拉起进程 | 接收 AMS 窗口请求 → 分配 SurfaceControl → 与 SurfaceFlinger 协同合成 | 查询 Intent 匹配 → 返回 ResolveInfo → AMS 据此启动组件 |
4.2 组件边界间的通信机制
三大服务虽然独立,但在一次完整的应用启动流程中必须紧密协作。通信核心机制是 Binder IPC,配合 系统服务代理(Service Proxy)与回调(Callback)实现跨进程数据流和控制流。
- AMS ↔ PMS:AMS 在启动 Activity 前调用 PMS.queryIntentActivities() 获取目标组件信息;PMS 返回 ResolveInfo 列表。这是“意图解析”的关键数据流。
- AMS ↔ WMS:AMS 创建 ActivityRecord 后通知 WMS.addWindow(),WMS 分配 WindowToken;窗口焦点变化时,WMS 回调 AMS.setFocusedWindow()。这是“窗口生命周期同步”的控制流。
- WMS ↔ PMS:WMS 一般不直接调用 PMS,但在主题(Theme)相关资源查询时可能通过 Context 间接访问 PMS 的元数据。
- 信任链路:所有跨服务调用均基于 SystemServer 进程内的 Binder 认证机制——只有系统 UID(system/1000)级别的服务才能注册为系统服务,应用进程无法冒充 AMS 或 WMS。
4.3 架构选型权衡:紧耦合 vs 模块化
在 AOSP 原生产品设计中,AMS、WMS、PMS 三者之间并非纯粹的“分层隔离”,而是存在大量双向依赖。这种设计带来性能优势,但也造成耦合风险。
| 选型维度 | 原生方案(紧耦合) | 替代方案(模块化解耦) | 权衡因素 |
|---|---|---|---|
| 生命周期复杂度 | AMS 直接持有 WMS/PMS 的 Binder 引用,调用链路短、延迟低 | 通过事件总线或回调接口解耦,增加中间层 | 紧耦合性能好,但调试难;解耦后可测试性提升,但会引入微秒级延迟 |
| 模块可替换性 | 替换任意服务需重写大量胶水代码,例如替换 WMS 需同时修改 AMS 的窗口回调 | 定义标准接口(IWindowManager/IActivityManager),通过依赖注入切换实现 | 原生适用于旗舰机,解耦适用于低内存/低功耗设备或定制架构 |
| 系统安全性 | 所有服务在同一进程内,权限检查依赖 UID 验证 | 服务分离到不同进程,使用 SELinux + Binder 权限控制 | 分离可缩小攻击面,但会增加 IPC 开销和同步复杂度 |
4.4 职责边界的内联框架结构
以下 SVG 图直观展示 AMS、WMS、PMS 在 SystemServer 进程内的定位,以及各自对应的外部系统交互关系。图中突出了三大服务之间的控制流和数据流方向,并标出信任链路的边界。
4.5 落地步骤与风险点
在实际 AOSP 组件化改造或架构学习实验中,建议按以下步骤拆解三大服务,并关注对应的风险。
- 步骤一:日志埋点与调用链追踪
在 AMS 的 startActivityLocked()、WMS 的 addWindow()、PMS 的 queryIntentActivities() 中植入原子日志,构建从用户点击到窗口渲染的完整控制流。
- 步骤二:接口依赖图绘制
基于
IActivityManager.aidl、IWindowManager.aidl、IPackageManager.aidl提取方法签名,识别出 双向依赖(如 AMS→WMS.addWindow 与 WMS→AMS.setFocusedWindow)。 - 步骤三:模拟异常场景
人为制造 WMS 响应超时或 PMS 返回 null,观察 AMS 的 fallback 策略(如重试、抛出 DeadObjectException、回滚到桌面)。
- 步骤四:增量解耦实验
在自定义 ROM 中将 PMS 从 SystemServer 中移出为独立进程,记录 IPC 次数和延迟增量,评估模块化带来的性能代价。
- 窗口泄漏:AMS 未及时通知 WMS 移除已销毁 Activity 对应的 WindowState,导致内存泄漏或 ANR。
- 签名不一致:PMS 缓存 APK 签名信息与应用运行时签名检查不同步,导致权限绕过或安全崩溃。
- Binder 回调顺序紊乱:AMS 先发起窗口请求,再绑定进程,若 WMS 回调到达时 ActivityRecord 尚未就绪,引发空指针。
- 资源锁竞争:AMS 和 PMS 同时持有锁(如 mActivities、mPackages)时可能形成死锁,需通过锁排序(先 PMS 后 AMS)规避。
4.6 验收标准
完成本章内容学习或实验后,应能达成以下验收目标:
| 验收项 | 验收标准 | 关联维度 |
|---|---|---|
| 职责边界理解 | 能口述 AMS、WMS、PMS 的核心职责,并举例说明重叠区域(如 Activity 窗口创建时双方如何协作) | 认知检查 |
| 通信链路绘制 | 能在白板上画出三条及以上 Binder 调用路径(AMS→PMS、AMS→WMS、WMS→AMS 回调),并标注数据方向 | 图形化输出 |
| 安全信任分析 | 能解释为什么应用进程无法伪造 AMS 或 WMS 调用(UID 检查 + Binder 认证 + 启动链信任) | 安全认知 |
| 场景识别 | 给定一个 ANR 日志片段(如 “Waiting in ActivityManager idle”),能判断是 AMS 阻塞还是 WMS 响应延迟 | 故障诊断 |
| 解耦评估 | 能列出将 PMS 移出 SystemServer 至少三个性能影响(IPC 次数增加、锁竞争范围扩大、启动时间变化) | 架构权衡 |