Android Framework层包含大量系统服务,AMS、WMS、PMS之所以被单独拿出来讨论,是因为它们分别覆盖了组件生命周期、窗口显示和包管理三条主线。三者在开机阶段完成注册,在应用启动、安装、卸载、切换屏幕、分屏等场景中频繁通过Binder交换数据。理解它们的职责边界和协作方式,是分析Framework层异常与性能问题的关键。

从进程角度看,system_server 是三大服务的宿主进程,应用通过 Context 的 getSystemService 拿到 Binder 代理。AMS 管理 Activity、Service、BroadcastReceiver 和 ContentProvider,WMS 管理窗口的添加、布局和输入焦点,PMS 则维护 APK 安装信息与权限。三者的数据并不孤立:PMS 解析出的组件信息供 AMS 启动时查询,AMS 给 WMS 提供窗口令牌,WMS 再把 Surface 信息返回给应用端渲染。
一、开机阶段三大服务如何完成注册与初始化
Android系统启动后,init 进程拉起 Zygote,再由 Zygote fork 出 system_server。SystemServer 的 main 方法里会启动引导服务、核心服务和其他服务。AMS、WMS、PMS 都属于核心服务,但在不同版本中启动顺序略有差异。PackageManagerService 通常较早启动,因为后续服务可能需要读取系统包信息;ActivityManagerService 在 PMS 之后启动,并在 systemReady 阶段通知桌面;WindowManagerService 依赖 InputManagerService 和 DisplayManagerService,负责与 SurfaceFlinger 建立连接。
服务注册的本质是调用 ServiceManager.addService。AMS 通过 ActivityManagerService.Lifecycle.startService 返回代理并注册,WMS 由 WindowManagerService.main 创建,PMS 通过 PackageManagerService.main 建实例。注册完成后,应用进程可以通过 Binder 获取对应服务。这里要注意 PMS 的名字固定为 package,而 AMS 和 WMS 对应 Context.ACTIVITY_SERVICE 与 Context.WINDOW_SERVICE。开发者常用的 getSystemService 最终会从 ServiceManager 缓存中查询这些 Binder 句柄。
public final class SystemServer {
private void startCoreServices() {
// PackageManagerService负责APK安装、权限和组件解析
PackageManagerService pms = PackageManagerService.main(mSystemContext, installer);
// ActivityManagerService负责组件生命周期、任务栈和进程管理
ActivityManagerService ams = new ActivityManagerService(mSystemContext);
// WindowManagerService负责窗口层级、输入焦点和Surface分配
WindowManagerService wms = new WindowManagerService(mSystemContext, inputManager);
ServiceManager.addService(Context.ACTIVITY_SERVICE, ams);
ServiceManager.addService(Context.WINDOW_SERVICE, wms);
ServiceManager.addService("package", pms);
}
}
从初始化内容看,PMS会扫描 /system/priv-app、/system/app、/data/app 等目录,解析 APK 中的 AndroidManifest.xml,生成 PackageParser.Package 对象,并写入 /data/system/packages.xml。AMS 初始化时创建 ActivityTaskManagerService、ProcessList 等内部模块,ActivityDisplay 和 ActivityStack 结构也会准备好。WMS 则向 InputManager 注册输入通道,并创建 WindowHashMap 来维护所有窗口。三者的初始化顺序保证了系统服务在桌面启动前具备完整能力。
二、点击图标启动应用时三者的协同过程
用户点击桌面图标后,Launcher 先构造一个 ACTION_MAIN、CATEGORY_LAUNCHER 的 Intent,并通过 Binder 调用 AMS 的 startActivity。AMS 不会直接读取 APK,而是先到 PMS 里执行 resolveActivity,根据 <intent-filter> 匹配出目标 Activity。PMS 返回 ResolveInfo 后,AMS 再检查目标进程是否存在。若不存在,AMS 向 Zygote 发送 fork 请求,新进程启动后会加载 ActivityThread 并完成 Application 初始化。
在 AMS 侧,一次启动会创建 ActivityRecord、Task 和 ProcessRecord。ActivityRecord 记录单个 Activity 状态,Task 对应返回栈,ProcessRecord 描述进程的优先级。AMS 把启动请求封装为 ClientTransaction,回调应用进程的 ActivityThread。应用端创建 Activity 实例并走 onCreate、onStart、onResume。此时 Activity 的窗口还没有真正显示,必须等到 WindowManagerGlobal.addView 触发 WMS.addWindow。
WMS 收到窗口添加请求后,会校验窗口令牌。这个 token 正是 AMS 在创建 ActivityRecord 时生成的,普通悬浮窗如果没有合法 token 会被 WMS 拒绝。校验通过后,WMS 创建 WindowState 并分配 Surface,然后通过 SurfaceFlinger 合成。ViewRootImpl 随后执行 relayout 和 draw,把内容渲染到 Surface 上。整个过程中,PMS 提供组件元数据,AMS 维护生命周期和任务栈,WMS 负责可见性、层级和输入焦点。
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(new ComponentName("com.example.app", "com.example.app.MainActivity"));
startActivity(intent);
显式指定 ComponentName 时,PMS 仍会校验该包是否存在对应 Activity,但不会再做完整的 Intent 过滤匹配。这可以缩短启动链路,也能避免隐式 Intent 匹配到多个组件时产生的不确定性。
三、PMS如何支撑包解析、权限与安装更新
PMS 启动后会扫描 /system/priv-app、/system/app、/data/app 等目录,逐个解析 APK 中的 AndroidManifest.xml。解析出的四大组件、权限、provider 等信息会封装成 Package 对象,并写入 /data/system/packages.xml。PMS 内部维护 mPackages、mActivities、mServices、mReceivers、mProviders 等多个 Map,AMS 的组件启动请求最终都会转化为对这些 Map 的查询。
权限机制是 PMS 的重要部分。安装时 PMS 解析 <uses-permission> 元素,把普通权限授予应用,危险权限则留到运行时动态申请。PMS 与 PermissionManagerService 协作,向 AMS 和 AppOps 提供权限检查结果。组件匹配同样依赖 PMS:queryIntentActivities 会遍历 mActivities,逐个比对 <intent-filter> 中的 action、category 和 data。AMS 启动组件时拿到的 ResolveInfo 就来自这里。
更新和卸载同样围绕 PMS。更新时系统会先把新 APK 放到 data/app 下,扫描并优化 dex,最后替换 packages.xml 中的记录。卸载则删除对应目录并广播 PACKAGE_REMOVED。整个过程通过 PackageInstaller 和 PackageManagerService 的回调完成。PMS 还维护 mSettings 保存包信息,确保设备重启后能恢复安装状态。
PackageManager pm = getPackageManager();
try {
PackageInfo info = pm.getPackageInfo("com.example.app", PackageManager.GET_PERMISSIONS);
String[] permissions = info.requestedPermissions;
long firstInstallTime = info.firstInstallTime;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
通过 PackageManager 公开接口只能读取应用自身能访问的信息,底层仍然由 PMS 完成权限过滤。查询所有可启动 Activity 时,PMS 会比较调用方 UID 与目标组件的 exported 属性,避免把未导出组件泄露给其他应用。
四、AMS的任务栈、进程优先级与生命周期管理
AMS 的核心数据结构包括 ActivityRecord、TaskRecord、ActivityStack 和 ProcessRecord。ActivityRecord 对应一个 Activity 实例,保存 state、packageName、launchMode 等字段;TaskRecord 是一组 ActivityRecord,按启动顺序排列;ActivityStack 管理多个 Task。Android 高版本把任务栈逻辑拆到 ActivityTaskManagerService,但设计思路一致。LaunchMode 决定栈内复用策略,standard 总会新建,singleTop 栈顶复用,singleTask 清理上方 Activity,singleInstance 独占一个 Task。
进程优先级由 AMS 动态计算。ProcessRecord 中的 adj 值根据组件状态调整:前台 Activity 进程 adj 为 0,可见进程 adj 为 100,服务进程 adj 为 200,后台进程 adj 为 400,空进程 adj 为 500。adj 越低越不容易被回收。AMS 把这些值同步给 lmkd,内存紧张时从 adj 高的进程开始杀。应用收到 onTrimMemory 也与其当前状态相关。
生命周期调度不是直接调用,而是通过 ClientTransaction 下发。ActivityThread 内部 Handler 处理 BIND_APPLICATION、LAUNCH_ACTIVITY、RESUME_ACTIVITY 等消息。AMS 维护每个 ActivityRecord 的状态,防止重复回调。如果应用进程异常退出,AMS 会清理对应 ProcessRecord 并恢复任务栈。
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.AppTask> tasks = am.getAppTasks();
for (ActivityManager.AppTask task : tasks) {
String packageName = task.getTaskInfo().topActivity.getPackageName();
}
上面的 API 默认只返回调用方自己的任务,无法查看其他应用的任务信息。要查看全局任务需要系统权限或使用系统级调试接口,这也体现了 AMS 对应用可见性的约束。
五、WMS窗口层级、令牌与SurfaceFlinger合成
WMS 为每个窗口维护一个 WindowState 对象,包含 WindowManager.LayoutParams 和窗口 token。窗口类型分应用窗口、子窗口和系统窗口,分别用 TYPE_APPLICATION、TYPE_APPLICATION_PANEL、TYPE_STATUS_BAR 等常量表示。层级主要由 type 和 z-order 决定,type 数值越大通常越靠上。输入法窗口、Toast、系统弹窗都通过 WMS 添加,统一由它控制可见性和焦点。
窗口令牌是 WMS 的安全核心。WindowManager.LayoutParams.token 用于标识父窗口或 Activity 窗口。应用窗口的 token 来自 AMS 的 ActivityRecord,WMS 通过 mTokenMap 做校验,防止恶意应用伪造系统窗口。分屏和自由窗口同样依赖 token 与窗口模式,WMS 会根据窗口模式重新计算边距和层级。
Surface 分配由 WMS 调用 WindowSurfacePlacer 完成。它通过 SurfaceControl 创建或更新 Surface,应用端在 ViewRootImpl 中拿到 Surface 后执行绘制。SurfaceFlinger 接收所有层,按 Z 轴顺序合成后输出到屏幕。WMS 不直接绘制像素,只管理窗口几何属性、可见区域和动画,这也是很多窗口问题需要同时查看 WMS 与 SurfaceFlinger 日志的原因。
if (Settings.canDrawOverlays(this)) {
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
wm.addView(view, params);
}
悬浮窗在 Android 8.0 及以上需要用户通过设置页授予显示在其他应用上层的权限,否则 Settings.canDrawOverlays 返回 false,直接调用 addView 会抛 SecurityException。
总地来说,AMS、WMS、PMS 分别解决应用生命周期、窗口显示和包管理三个独立问题,但它们的协作贯穿所有核心场景。PMS 解析静态信息,AMS 驱动进程和组件,WMS 完成最终可见性。排查黑屏、启动失败、窗口乱层等问题时,沿着 PMS 到 AMS 再到 WMS 的调用链分析,通常能快速定位根因。