Android 系统层扫盲 09:AMS、ATMS、WMS、PMS 到底分别管什么?

前面我们已经知道:

复制代码
Zygote
↓
system_server
↓
SystemServer
↓
启动大量 System Service

然后第八篇又把:

复制代码
App
↓
Binder
↓
system_server
↓
System Service

这条路跑通了。

现在终于可以正式认识 Android Framework 中最常见的几个"大佬":

复制代码
AMS

ATMS

WMS

PMS

这几个缩写在 Framework 源码里几乎无处不在。

但第一次学的时候非常容易混:

复制代码
AMS 不是管 Activity 吗?

那 ATMS 又是什么?

WMS 是不是负责画界面?

PMS 是不是就负责安装 APK?

这一篇就把它们彻底分开。

而且我们不只背定义。

最后会用一个最熟悉的场景:

用户在 Launcher 点击一个 App 图标。

看看:

复制代码
PMS
ATMS
AMS
WMS

到底分别在哪一步出现。


一、先给四个 Service 一句话定位

先不管细节。

直接记:

复制代码
PMS
=
这个 App 是谁?
里面有什么组件?
这个 Intent 能启动谁?

ATMS
=
这个 Activity 怎么启动?
放进哪个 Task?
谁在前台?
Activity / Task 怎么组织?

AMS
=
这个 App 进程活没活?
要不要启动进程?
Service / Broadcast / Provider 怎么管理?

WMS
=
窗口放哪里?
多大?
谁在最上面?
谁获得焦点?
怎么和显示、输入、Surface 协作?

如果再加一个:

复制代码
SurfaceFlinger
=
最后把多个 Surface 真正合成到屏幕上

这张地图先建立起来。


二、最容易搞错的是 AMS

很多老 Android Framework 教程都会说:

复制代码
AMS
=
ActivityManagerService
=
管理 Activity

这个说法:

放在历史 Android 中有它的背景,但放到现代 Android 已经不够准确。

因为现代 Android 已经把大量:

复制代码
Activity
Task
Display 上的 Activity Container

相关管理职责拆到了:

复制代码
ATMS

也就是:

复制代码
ActivityTaskManagerService

当前 AOSP 对 ATMS 的源码注释直接写的是:

管理 Activity 以及它们的容器,例如 Task、Display。

所以现在第一阶段最好直接记:

复制代码
Activity / Task
↓
ATMS

而不是继续简单记:

复制代码
Activity
↓
AMS

三、ATMS 全称是什么?

复制代码
ActivityTaskManagerService

拆开:

复制代码
Activity
+
Task
+
Manager
+
Service

名字其实已经把职责写出来了:

Activity 和 Task 的系统级管理服务。

例如:

复制代码
启动哪个 Activity?

这个 Activity 放到哪个 Task?

是不是创建新 Task?

是不是复用已有 Task?

哪个 Activity 在前台?

Task 怎么切换?

Activity 属于哪个 Display?

这些都是 ATMS 世界。

当前源码:

复制代码
public class ActivityTaskManagerService
        extends IActivityTaskManager.Stub

所以它本身就是一个 Binder Service。


四、你平时 startActivity() 已经在和 ATMS 打交道

我们平时:

复制代码
startActivity(intent)

看起来只是:

复制代码
Context
↓
startActivity()

但现代 Android 中,Framework 最终会进入:

复制代码
ActivityTaskManager.getService()

然后调用:

复制代码
IActivityTaskManager

跨 Binder 进入:

复制代码
ActivityTaskManagerService

当前 AOSP 的 ContextImpl 中,startActivityAsUser() 就直接调用:

复制代码
ActivityTaskManager.getService()
    .startActivityAsUser(...)

所以现代心智模型:

复制代码
App

startActivity()
↓
ActivityTaskManager
↓
IActivityTaskManager.Proxy
↓
Binder
↓
ATMS

system_server

五、那为什么老源码里总看到 AMS.startActivity()?

因为 Android 架构是一路演化过来的。

AMS 曾经承担非常广泛的 Activity 管理职责。

后来:

复制代码
Activity / Task

相关大量代码逐渐拆到:

复制代码
com.android.server.wm

这一套体系中。

现代源码里有些 AMS 的 Activity 启动接口仍然存在,但你可以看到它会继续转给:

复制代码
mActivityTaskManager

也就是 ATMS。

所以以后看到老教程:

复制代码
startActivity
↓
AMS

不要立刻认为:

教程全错了。

更准确的理解是:

Android 架构演进以后,Activity / Task 的核心管理职责已经主要由 ATMS 承担。


六、所以 AMS 现在主要干什么?

AMS:

复制代码
ActivityManagerService

虽然名字还有:

复制代码
Activity

但现代 Android 中,更适合把它理解成:

App 运行状态和进程级组件管理中心。

主要涉及:

复制代码
App Process

Service

Broadcast

ContentProvider

进程状态

OOM 调整

前后台状态

ANR 等运行管理

等等。

第一阶段最值得记的是:

复制代码
AMS
=
更偏 App / Process 运行管理

七、Service 就明显还是 AMS 的世界

例如我们平时:

复制代码
startService(intent)

当前 Android Framework 中会通过:

复制代码
ActivityManager.getService()

调用:

复制代码
IActivityManager.startService()

最终进入 AMS。当前 ContextImplActivityManagerService 源码仍然保持这条关系。

所以:

复制代码
startActivity()
↓
偏 ATMS

而:

复制代码
startService()
↓
偏 AMS

这一下就开始分开了。


八、Broadcast 也是 AMS 这一侧的重要职责

比如:

复制代码
sendBroadcast(intent)

Framework 会进入:

复制代码
ActivityManager.getService()

然后通过:

复制代码
IActivityManager

进入 system_server。

当前 ContextImpl 中的 Broadcast 发送仍然通过 ActivityManager Binder 接口完成。

所以:

复制代码
Service
Broadcast
Provider
Process

这些东西看到:

复制代码
AMS

就很正常。


九、AMS 还有一个极其重要的职责:Process

这个和前面 Zygote 能直接串起来。

假设:

复制代码
ATMS

准备启动:

复制代码
MainActivity

但发现:

复制代码
这个 App Process
根本还不存在

怎么办?

Activity / Task 是 ATMS 管。

但是:

Linux App Process 的启动管理仍然要和 AMS 这一侧协作。

当前 ATMS 源码中,可以直接看到它通过:

复制代码
ActivityManagerInternal.startProcess()

把进程启动请求交给 ActivityManager 体系处理。源码甚至明确写着:

复制代码
calling into AMS

所以可以理解:

复制代码
ATMS

我准备启动 Activity
↓
发现 App Process 不存在
↓
找 AMS
↓
请启动这个 App Process

十、然后 AMS 再和 Zygote 联系起来

前面第六篇已经学过:

复制代码
Zygote
=
App Process 工厂

所以:

复制代码
AMS / ProcessList
↓
请求创建 App Process
↓
Zygote
↓
fork
↓
新的 App Process

这时候前面的文章开始真正接起来了。

也就是说:

复制代码
ATMS

不是自己:

复制代码
fork()

App。

它负责:

我要启动哪个 Activity。

AMS / Process 管理体系负责:

这个 Activity 所属的进程要不要创建。

最终:

复制代码
Zygote

负责:

真正 fork 出进程。


十一、所以 AMS 和 ATMS 不是竞争关系

不要理解成:

复制代码
以前 AMS

现在 ATMS

所以 AMS 没用了

完全不是。

更像:

复制代码
ATMS
=
Activity / Task 负责人

AMS
=
Process / App Runtime 负责人

启动 Activity 时:

复制代码
ATMS
↕
AMS

两边会大量合作。

例如:

复制代码
ATMS:
我要启动 MainActivity


AMS:
对应进程还没起来


AMS → Zygote:
创建进程


Zygote:
fork App Process


ATMS:
继续安排 Activity 启动

所以:

拆分职责,不代表彼此没有关系。


十二、下面看 PMS

PMS:

复制代码
PackageManagerService

这个 App 开发者应该也很熟。

因为平时经常:

复制代码
packageManager

查询:

复制代码
ApplicationInfo

PackageInfo

ActivityInfo

ResolveInfo

等等。

App 侧:

复制代码
PackageManager

背后系统侧的重要服务就是:

复制代码
PackageManagerService

PMS 当前依然是:

复制代码
IPackageManager.Stub

这一 Binder Service 体系的核心实现。


十三、PMS 绝不只是"安装 APK"

很多人第一印象:

复制代码
PackageManagerService
=
安装 / 卸载 APK

其实远远不止。

PMS 掌握 Android 中非常重要的一套:

复制代码
Package
Application
Activity
Service
Receiver
Provider
IntentFilter
签名
权限声明
UID / User 下的包状态

相关信息。

所以可以把 PMS 想成:

Android App 世界的户籍系统 + 组件数据库。


十四、APK 安装的时候 PMS 会做大量工作

一个 APK 进入系统以后,需要知道:

复制代码
包名是什么?

versionCode 是多少?

签名是什么?

声明了哪些 Activity?

有哪些 Service?

有哪些 Receiver?

有哪些 Provider?

有哪些 IntentFilter?

请求了哪些 Permission?

这些信息最终都会进入系统的 Package 管理体系。

所以以后 Android 想知道:

复制代码
com.xxx.app

到底是什么:

就离不开 PMS / PackageManager 这一整套体系。


十五、为什么启动 Activity 也离不开 PMS?

假设:

复制代码
val intent =
    Intent(Intent.ACTION_VIEW, uri)

startActivity(intent)

这里甚至没有告诉系统:

复制代码
具体启动哪个 Activity

那 Android 怎么知道谁能处理?

必须:

复制代码
查询安装的 Package
↓
查看各组件 IntentFilter
↓
匹配 Activity

这就是:

复制代码
Intent Resolve

PackageManager 当前仍然提供大量:

复制代码
queryIntentActivities()
resolveIntent()
getActivityInfo()

等能力;PMS 内部也有对应的 Activity 查询和 Intent 匹配体系。

所以:

复制代码
PMS

非常重要的一项能力就是:

告诉系统"这个 Intent 到底对应哪个组件"。


十六、Launcher 本身就大量依赖 PMS

你桌面看到:

复制代码
微信
地图
相机
自己的 App

Launcher 怎么知道:

复制代码
安装了哪些 App?

哪个 Activity 是 Launcher Activity?

App 图标是什么?

App 名称是什么?

这些都需要:

复制代码
PackageManager

提供 Package / Activity 信息。

所以其实在你:

点击 App 图标之前

PMS 就已经参与进来了。

Launcher 展示那个图标,本身就是建立在 Package 管理信息上的。


十七、PMS 可以简单记成"身份和能力数据库"

以后看到 PMS:

先想到几个词:

复制代码
Package

Manifest

Component

Intent Resolve

Signature

Permission Declaration

Install / Uninstall

可以把它总结成一句:

PMS 负责回答"系统里到底装了什么,以及这些 App 能提供什么组件能力"。

注意现代 Android 的权限体系内部也有专门的 Permission Manager 等组件,所以第一阶段不要简单理解成:

复制代码
所有权限逻辑
=
PMS 一个类全包

Android 已经高度模块化。

但 Package、组件、签名、权限声明和安装状态,依然和 Package Manager 体系紧密相关。


十八、下面看 WMS

WMS:

复制代码
WindowManagerService

这个也非常容易理解错。

很多人看到:

复制代码
WindowManager

就觉得:

是不是负责画 UI?

不是。

至少不能这么理解。


十九、WMS 首先管理的是 Window

Activity 启动以后:

复制代码
Activity
↓
Window

一个 Window 可以包含:

复制代码
DecorView
↓
View Hierarchy

但系统中不只有 Activity Window。

还有:

复制代码
Dialog

输入法窗口

系统栏

壁纸

各种系统 Window

等等。

所以系统必须有一个全局角色管理:

复制代码
现在系统里有哪些 Window?

哪个 Window 在前面?

哪个 Window 有焦点?

Window 属于哪个 Display?

Window 大小是多少?

位置在哪里?

层级是什么?

这个角色就是:

复制代码
WMS

二十、WMS 更像"窗口管理员"

可以把屏幕想象成:

复制代码
一栋写字楼

每个 Window 是:

复制代码
一个房间

WMS 关心:

复制代码
房间在哪一层?

面积多大?

谁压在谁上面?

哪个房间现在获得焦点?

哪个房间能接收输入?

窗口什么时候进入 / 退出?

但:

房间里面具体画什么内容,不是 WMS 自己画。


二十一、所以 WMS 不负责真正画 View

你的:

复制代码
Text
Image
Compose
View
Canvas

最终产生图形 Buffer。

App 自己负责:

复制代码
UI 构建
Measure
Layout
Draw
Render

然后把图形内容送进:

复制代码
Surface

WMS 负责的更多是:

复制代码
Window 管理

Window Metadata

位置

层级

Focus

Transition

Display

Input 协调

Android 官方对 WindowManager 的描述也明确包含窗口生命周期、焦点、输入、旋转、动画、位置、变换、Z-order 等职责。


二十二、真正把画面合成到屏幕的是谁?

这里必须引出:

复制代码
SurfaceFlinger

App 可以产生:

复制代码
Surface A

Surface B

Surface C

比如:

复制代码
App Window

Status Bar

Navigation Bar

其他 Layer

最终:

复制代码
SurfaceFlinger

拿到这些可见 Surface 的 Buffer:

复制代码
Surface A
Surface B
Surface C
↓
Composition
↓
Display

官方 Android Graphics 文档明确说明:

SurfaceFlinger 接收来自多个来源的 Buffer,将它们合成,并送到 Display。

所以:

复制代码
WMS
≠
SurfaceFlinger

二十三、WMS 和 SurfaceFlinger 怎么分工?

非常简单:

复制代码
WMS
=
管窗口

SurfaceFlinger
=
管 Surface 合成

例如:

复制代码
这个 Window 在哪里?

大小多少?

Z-order 是多少?

做什么 Transform?

WMS 管。

然后:

复制代码
这些 Surface Buffer
最后怎么组合成屏幕上的一帧?

SurfaceFlinger 管。

官方文档也把两者关系描述为:

复制代码
WindowManager
↓
提供 Window Metadata / Surface 相关信息
↓
SurfaceFlinger
↓
合成显示

二十四、所以千万不要记成 WMS = 画屏幕

错误:

复制代码
WMS
↓
负责把 UI 画到屏幕

更准确:

复制代码
App
↓
产生 UI Buffer
↓
Surface

WMS
↓
管理 Window / Surface 的系统级关系

SurfaceFlinger
↓
合成各个 Surface
↓
Display

二十五、现在四个 Service 已经可以放到一起了

先用一句最简单的话:

复制代码
PMS
=
你是谁?

ATMS
=
Activity 怎么组织?

AMS
=
进程和 App 组件怎么运行?

WMS
=
窗口怎么管理?

再加:

复制代码
SurfaceFlinger
=
画面最终怎么合成?

二十六、用公司部门来类比一下

假设 Android 是一家公司。

PMS:

复制代码
人事 / 档案部

它知道:

复制代码
有哪些员工?

叫什么?

属于哪个部门?

有什么权限?

能做什么?

ATMS:

复制代码
业务调度部

负责:

复制代码
当前哪个 Activity 工作?

属于哪个 Task?

接下来切到谁?

AMS:

复制代码
运营管理部

负责:

复制代码
整个 App Process 怎么运行?

哪些 Service 在跑?

Broadcast 怎么调度?

进程什么时候创建和回收?

WMS:

复制代码
办公空间管理部

负责:

复制代码
哪个窗口在哪?

多大?

谁盖住谁?

谁有焦点?

SurfaceFlinger:

复制代码
最后的显示合成部门

把所有窗口内容:

复制代码
真正组合成最终屏幕画面

二十七、现在进入这一篇最重要的例子

假设手机当前停在:

复制代码
Launcher

桌面上有一个:

复制代码
Demo App

用户点击:

复制代码
Demo App 图标

然后:

复制代码
MainActivity

出现在屏幕上。

这一件看起来再普通不过的事情:

其实会把前面这些服务几乎全部串起来。


二十八、第一步:Launcher 为什么知道这个 App 能启动?

在点击之前:

复制代码
Launcher

已经需要知道:

复制代码
哪些 App 有 Launcher Activity?

名称是什么?

图标是什么?

启动组件是什么?

这些信息来自:

复制代码
PackageManager
↓
Package Manager System

所以:

复制代码
PMS

其实很早就已经参与了。

可以简单理解:

复制代码
PMS

告诉 Launcher:

Demo App
↓
Launcher Activity
↓
MainActivity

二十九、第二步:用户点击图标

Launcher 最终发起:

复制代码
startActivity(intent)

这里就从:

复制代码
Package 世界

进入:

复制代码
Activity / Task 世界

现代 Android:

复制代码
Launcher
↓
startActivity()
↓
ActivityTaskManager
↓
IActivityTaskManager
↓
Binder
↓
ATMS

所以:

真正负责"我要启动一个 Activity"这件事的核心角色开始变成 ATMS。


三十、第三步:ATMS 先搞清楚到底启动谁

ATMS 收到 Intent。

系统需要确认:

复制代码
目标 Activity 是谁?

ActivityInfo 是什么?

属于哪个 Package?

processName 是什么?

launchMode 是什么?

有没有权限限制?

这里就需要:

复制代码
Package Manager

提供组件和 Package 信息。

可以粗略理解:

复制代码
ATMS
↓
Package Manager 能力
↓
得到 ActivityInfo
↓
确认目标 Activity

所以:

复制代码
ATMS

负责:

我要怎么启动这个 Activity。

PMS:

这个 Activity 到底是谁。


三十一、第四步:ATMS 开始处理 Task

找到:

复制代码
MainActivity

以后,并不是立刻:

复制代码
new MainActivity()

ATMS 还要考虑:

复制代码
它应该进入哪个 Task?

要不要新建 Task?

是不是 singleTop?

是不是 singleTask?

FLAG_ACTIVITY_NEW_TASK 怎么处理?

原来的 Task 能不能复用?

哪个 Activity 要暂停?

哪个 Activity 要切到后台?

这些就是:

复制代码
Activity / Task

管理。

也就是 ATMS 最核心的职责。


三十二、所以 launchMode 为什么是系统级问题?

我们 App 开发经常写:

复制代码
android:launchMode="singleTop"

以前可能只是:

背几个启动模式规则。

现在就能理解:

复制代码
singleTop

singleTask

Task

Back Stack

这些东西根本不是:

复制代码
Activity 自己决定

而是:

系统 Activity / Task 管理体系决定。

现代 Android 中,这一块主要就是:

复制代码
ATMS

三十三、第五步:发现目标 App Process 不存在

现在 ATMS 已经决定:

复制代码
我要启动 DemoActivity

但是发现:

复制代码
com.demo

进程根本不存在。

这时候:

复制代码
ATMS

不能直接:

复制代码
new Activity()

因为 Activity 必须运行在:

复制代码
App Process

里。

于是:

复制代码
ATMS
↓
ActivityManagerInternal
↓
AMS / Process 管理体系

请求启动进程。当前 ATMS 源码中的 startProcessAsync() 就会把进程启动交给 ActivityManagerInternal。


三十四、第六步:AMS 请求创建 App Process

于是:

复制代码
AMS

这边开始处理:

复制代码
Demo App Process

它会准备:

复制代码
processName

ApplicationInfo

UID

ABI

Hosting 信息

等等。

最终进入进程创建体系:

复制代码
AMS / ProcessList
↓
Zygote

三十五、第七步:Zygote fork

这个就完全回到第六篇了:

复制代码
system_server
↓
请求 Zygote
↓
Zygote fork()
↓
新的 App Process

然后:

复制代码
App Process
↓
ActivityThread

开始运行。

你现在会发现:

复制代码
Zygote
AMS
ATMS

已经连起来了。


三十六、第八步:App Process 启动后,Activity 真正被创建

新的 App Process 起来:

复制代码
ActivityThread.main()
↓
Looper
↓
ApplicationThread

然后 system_server 可以通过 Binder:

复制代码
system_server
↓
IApplicationThread
↓
App Process

向 App 发调度命令。

最终 App 侧:

复制代码
ActivityThread
↓
创建 Application
↓
创建 Activity
↓
onCreate()
↓
onStart()
↓
onResume()

这里就是我们 App 开发天天写的生命周期。

后面第十篇:

Activity 启动流程

会专门把这条线完整展开。


三十七、第九步:Activity 有了,但屏幕上还没有 Window

Activity:

复制代码
onCreate()

执行了以后:

会建立:

复制代码
Window

例如常见的:

复制代码
PhoneWindow

里面:

复制代码
DecorView
↓
View Hierarchy

但:

本地有一个 Window 对象,不代表系统已经接受了这个窗口。

因为整个 Android 屏幕:

复制代码
不可能由每个 App 自己随便放 Window

所以还必须告诉:

复制代码
WMS

三十八、第十步:Window 进入 WMS

App 侧窗口体系最终会通过:

复制代码
IWindowManager
IWindowSession

等 Binder 接口和:

复制代码
WindowManagerService

通信。

于是:

复制代码
App Process

Activity
↓
Window
↓
WindowManagerGlobal / ViewRootImpl
↓
Binder

==================

system_server

WMS

WMS 开始知道:

复制代码
系统里出现了一个新的 App Window

三十九、WMS 接下来管什么?

WMS 会参与决定:

复制代码
Window Token

Display

Window Size

Position

Insets

Focus

Z-order

Transition

Input Region

等等。

也就是说:

复制代码
Activity

解决:

业务页面生命周期。

复制代码
Window

解决:

页面在系统显示体系里的窗口载体。

复制代码
WMS

解决:

所有 Window 在整个系统中的全局管理。


四十、然后 App 才开始真正产生画面

App 自己:

复制代码
View / Compose
↓
Measure
↓
Layout
↓
Draw
↓
Render

产生:

复制代码
Graphic Buffer

进入:

复制代码
Surface

四十一、最后 SurfaceFlinger 合成

于是:

复制代码
Demo App Surface

Launcher / Transition Surface

Status Bar Surface

Navigation Bar Surface

等等。

最终:

复制代码
SurfaceFlinger
↓
Composition
↓
Display

于是用户终于看到:

复制代码
Demo App MainActivity

四十二、完整链路终于出来了

用户点击 Launcher 图标:

复制代码
Launcher
↓
PMS / Package Manager
↓
知道目标 App / Activity
↓
startActivity()
↓
ActivityTaskManager
↓
Binder
↓
ATMS
↓
解析 Activity / Task
↓
判断目标进程

如果进程不存在:

复制代码
ATMS
↓
AMS
↓
Process 管理
↓
Zygote
↓
fork
↓
App Process

然后:

复制代码
ActivityThread
↓
Application
↓
Activity
↓
Window
↓
WMS
↓
Surface
↓
SurfaceFlinger
↓
Display

这就是:

点击一个 App 图标背后的系统级故事。


四十三、现在四个 Service 在这条链里的作用非常清楚了

PMS

复制代码
Demo App 是谁?

MainActivity 是谁?

Package 有哪些组件?

Intent 对应谁?

所以:

复制代码
PMS
=
身份 / Package / Component

ATMS

复制代码
启动哪个 Activity?

属于哪个 Task?

Task 怎么组织?

哪个 Activity 在前台?

所以:

复制代码
ATMS
=
Activity / Task 调度

AMS

复制代码
目标进程存在吗?

要不要启动?

Service 怎么运行?

Broadcast 怎么调度?

Provider / Process 状态怎么管理?

所以:

复制代码
AMS
=
App Process / Runtime 管理

WMS

复制代码
Window 在哪?

大小多少?

谁有焦点?

谁在最上层?

属于哪个 Display?

所以:

复制代码
WMS
=
Window 管理

四十四、再加入 SurfaceFlinger 就彻底不乱了

复制代码
PMS
=
应用是谁

ATMS
=
Activity 怎么跑

AMS
=
进程怎么活

WMS
=
窗口怎么放

SurfaceFlinger
=
画面怎么合

这五句话非常值得记。


四十五、Manager 和 Service 也不要混

App 侧经常看到:

复制代码
ActivityManager

ActivityTaskManager

WindowManager

PackageManager

system_server 侧则是:

复制代码
ActivityManagerService

ActivityTaskManagerService

WindowManagerService

PackageManagerService

可以粗略理解:

复制代码
App Process

Manager
↓
Binder Interface
↓
Binder

=====================

system_server

System Service

例如:

复制代码
ActivityTaskManager
↓
IActivityTaskManager
↓
Binder
↓
ActivityTaskManagerService

四十六、但不要强行认为所有 Manager 都是一模一样的结构

第一阶段可以用:

复制代码
Manager
↓
Binder
↓
Service

帮助理解。

但真正源码里每一套都有自己的封装。

比如 Window 体系会经过:

复制代码
WindowManagerImpl

WindowManagerGlobal

ViewRootImpl

IWindowSession

等等。

PackageManager 也有:

复制代码
ApplicationPackageManager

之类客户端实现。

所以:

先理解架构角色,不要第一阶段死背类之间的每一层关系。


四十七、为什么 ATMS 和 WMS 都在 com.android.server.wm?

如果以后看源码,会发现:

复制代码
ActivityTaskManagerService

居然也在:

复制代码
com.android.server.wm

而不是:

复制代码
com.android.server.am

这并不奇怪。

因为现代 Android 中:

复制代码
Activity

Task

Display Area

Window Container

Window

之间关系非常紧密。

ATMS 和 WMS 也确实存在大量协作;当前 WMS 创建接口本身就直接接收 ActivityTaskManagerService

所以现代 Android 的:

复制代码
Activity / Task / Window

越来越像一套紧密结合的:

Window Management / Window Container 系统。

第一阶段知道这个趋势就够了。


四十八、以后看到 startActivity 不要只想到 AMS

以前:

复制代码
startActivity()
↓
AMS

是很多人的肌肉记忆。

现在建议更新成:

复制代码
startActivity()
↓
ATMS
↓
Activity / Task

如果目标进程没起来:

复制代码
ATMS
↓
AMS
↓
Process
↓
Zygote

这是现代 Android 更清晰的理解方式。


四十九、以后看到 startService 则先想到 AMS

比如:

复制代码
startService(intent)

可以先想到:

复制代码
Context
↓
ActivityManager
↓
IActivityManager
↓
Binder
↓
AMS
↓
Service 管理体系

不要因为名字:

复制代码
ActivityManagerService

就觉得它只和 Activity 有关。

实际上现在:

复制代码
Service
Process
Broadcast
Provider

才是理解 AMS 时非常重要的一组关键词。


五十、以后看到 Intent 解析先想到 PMS

比如:

复制代码
ACTION_VIEW

ACTION_SEND

MAIN + LAUNCHER

系统需要判断:

复制代码
到底谁能处理?

先想到:

复制代码
PackageManager
PMS
Intent Resolver

就对了。


五十一、以后看到 Window / Focus / Insets 先想到 WMS

例如以后你看到:

复制代码
Window Focus

Window Token

Insets

Display

IME Window

Rotation

Transition

Window Layer

大概率已经进入:

复制代码
WMS / WindowManager

世界。

而不是:

复制代码
AMS

世界。


五十二、以后看到 Surface / Buffer / Composition 再想到 SurfaceFlinger

比如:

复制代码
BufferQueue

Surface

Layer

Composition

Hardware Composer

VSync

已经开始进入:

复制代码
Graphics
SurfaceFlinger

领域。

这和:

复制代码
WMS

虽然关系很紧,但不是一个职责。


五十三、第一阶段只需要建立这张地图

复制代码
                  Android Framework


       Package 信息
            │
            ↓
           PMS
            │
            │
            ↓
      Activity / Task
            │
            ↓
           ATMS
            │
      ┌─────┴─────┐
      │           │
      ↓           ↓
    AMS           WMS
      │           │
      ↓           ↓
 App Process    Window
      │           │
      ↓           ↓
   Zygote       Surface
                  │
                  ↓
            SurfaceFlinger
                  │
                  ↓
               Display

当然真实 Android 比这复杂得多。

但是第一阶段:

这张地图已经足够用了。


五十四、四个 Service 最终对比

Service 第一反应 核心关键词
PMS App 是谁 Package、Manifest、Component、Intent Resolve、Install
ATMS Activity 怎么组织 Activity、Task、Launch、Back Stack、Display
AMS App 怎么运行 Process、Service、Broadcast、Provider、OOM
WMS Window 怎么管理 Window、Focus、Display、Insets、Layer、Input

再额外记:

Service 核心关键词
SurfaceFlinger Surface、Buffer、Composition、Display

五十五、把前面九篇串起来

现在我们的主线已经变成:

复制代码
Linux Kernel
↓
init
↓
Zygote
↓
fork
↓
system_server
↓
SystemServer
↓
启动 System Service
↓
Binder
↓
App 可以调用 System Service
↓
AMS / ATMS / PMS / WMS

而 App 启动又可以:

复制代码
PMS
↓
ATMS
↓
AMS
↓
Zygote
↓
App Process
↓
ActivityThread
↓
Activity
↓
WMS
↓
SurfaceFlinger

到这里:

Android Framework 的"大地图"其实已经开始成型了。


五十六、一句话总结

如果只能记四句话:

复制代码
PMS
=
我是谁?

ATMS
=
Activity 去哪?

AMS
=
进程怎么活?

WMS
=
窗口怎么放?

再加一句:

复制代码
SurfaceFlinger
=
最后怎么显示?

就够了。

而一次 App 启动,本质上就是这些系统服务协作:

复制代码
PMS
↓
找到目标

ATMS
↓
安排 Activity / Task

AMS
↓
保证 App Process 存在

Zygote
↓
创建 App Process

ActivityThread
↓
真正创建 Activity

WMS
↓
管理 Window

SurfaceFlinger
↓
把 Surface 合成到屏幕

所以:

AMS、ATMS、PMS、WMS 并不是四个孤立的系统服务,而是 Android 从"找到 App → 启动页面 → 创建进程 → 管理窗口 → 最终显示"这一整条系统链路里的不同分工。


下一篇:

《Android 系统层扫盲 10:startActivity() 到底发生了什么?从 App 一路追到 Activity.onCreate()》

第九篇我们只是站在高处看:

复制代码
PMS
ATMS
AMS
Zygote
ActivityThread
WMS

分别干什么。

下一篇就只盯着一行代码:

复制代码
startActivity(intent)

真正往下追:

复制代码
App Process
↓
Instrumentation
↓
ActivityTaskManager
↓
Binder
↓
ATMS
↓
ActivityStarter
↓
PMS / Resolve
↓
Task
↓
AMS
↓
Zygote
↓
新 App Process
↓
ActivityThread
↓
ApplicationThread
↓
Activity 创建
↓
onCreate()

也就是说:

第九篇是"谁负责什么",第十篇正式看"它们到底怎么一起把一个 Activity 启动起来"。

相关推荐
Godikov1 小时前
Android 系统级设备应用踩坑实录:sharedUserId 签名、SDK 授权失败 -4、开机自启与 U 盘 OTA 升级
android
IT毕设实战小研4 小时前
基于大数据的国内主要农作物产量趋势分析与可视化
android·java·大数据·django·课程设计
企业数字化笔记6 小时前
固定资产历史数据怎么导入系统?Excel模板、字段映射和数据校验
android·java·数据库·后端
龙之叶6 小时前
Android出海系列-GMS认证介绍
android
潮族大Z6 小时前
Android性能优化:启动、内存、卡顿的一站式排查手册
android
事圆则缓8 小时前
从suspend字节码到 Retrofit 协程桥:挂起函数识别与恢复
android·retrofit
杉氧9 小时前
RN 性能调优指南:重渲染(Re-renders)控制与长列表(FlatList)优化
android·前端·react native
Coffeeee9 小时前
claude-video 一个让你的Agent拥有看视频能力的Skill
android·人工智能·aigc
菜鸟~noob23310 小时前
【电子战】第07篇:多普勒测向【含matlab代码】
android·开发语言·matlab