AMS与组件管理
# 06.AMS与组件管理
# 目录介绍
- 01.为什么需要AMS
- 1.1 组件管理的核心问题
- 1.2 AMS的职责范围
- 1.3 从系统启动看AMS的地位
- 02.AMS的整体架构设计
- 2.1 核心类关系
- 2.2 核心数据结构
- 2.3 Binder通信架构
- 03.AMS的启动与初始化流程
- 3.1 创建AMS实例
- 3.2 注册系统服务
- 3.3 systemReady阶段
- 04.Activity的管理机制
- 4.1 Activity启动的AMS侧处理
- 4.2 Activity的状态管理
- 4.3 Task和Back Stack管理
- 05.ActivityRecord与TaskRecord详解
- 5.1 ActivityRecord的完整字段
- 5.2 启动模式的Task影响
- 5.3 最近任务列表管理
- 06.Service的管理与生命周期
- 6.1 Service管理的核心类
- 6.2 startService的完整流程
- 6.3 Service的后台限制演进
- 07.Service的启动与绑定原理
- 7.1 bindService的流程
- 7.2 连接关系的数据结构
- 7.3 Service的ANR检测
- 08.BroadcastReceiver的注册与分发
- 8.1 动态注册的实现
- 8.2 广播分发的队列机制
- 8.3 sendBroadcast的完整流程
- 09.广播的有序与并行分发机制
- 9.1 并行广播分发
- 9.2 有序广播分发
- 9.3 广播超时与ANR
- 10.ContentProvider的启动与管理
- 10.1 ContentProvider的安装时机
- 10.2 AMS中的Provider管理
- 10.3 Provider的引用计数
- 11.ContentProvider的跨进程数据共享
- 11.1 数据传输机制
- 11.2 批量操作优化
- 11.3 ContentProvider的权限模型
- 12.进程管理与优先级调度
- 12.1 ProcessRecord详解
- 12.2 进程优先级体系
- 13.OOM_adj算法与进程回收
- 13.1 OOM_adj更新时机
- 13.2 进程回收策略
- 13.3 缓存进程的LRU管理
- 14.AMS中的ANR检测机制
- 14.1 ANR检测的整体设计
- 14.2 Input ANR检测流程
- 14.3 ANR信息收集
- 15.AMS与WMS的协作关系
- 15.1 协作架构
- 15.2 Activity启动时的AMS-WMS协作
- 15.3 转场动画的协调
- 15.4 从Android 10看架构统一
- 16.AMS的演进与ATMS重构
- 16.1 AMS的历史演进
- 16.2 ATMS拆分的设计思想
- 16.3 未来趋势
- 17.总结与技术思考
- 17.1 核心要点回顾
- 17.2 面试高频问题
- 17.3 学习建议
# 01.为什么需要AMS
# 1.1 组件管理的核心问题
Android系统中有四大组件:Activity、Service、BroadcastReceiver、ContentProvider。每个组件都有自己的生命周期和运行规则,它们可能运行在不同的进程中。那么问题来了:谁来统一管理这些组件的创建、调度和销毁?
如果让每个应用自己管理自己的组件,会出现什么问题?
第一个问题:进程间无法协调。A应用想启动B应用的Activity,如果没有一个统一的管理者,A根本不知道B在不在、B的Activity能不能启动。
第二个问题:资源无法统一调度。系统内存不足时,应该回收哪个进程?如果没有全局视角,根本无法做出合理的决策。
第三个问题:安全性无法保障。任何应用都可以随意启动其他应用的组件,那权限控制就形同虚设。
所以,Android系统需要一个全局的、运行在系统进程中的管理者,这就是AMS(ActivityManagerService)。
# 1.2 AMS的职责范围
AMS是Android系统中最核心的系统服务之一,运行在SystemServer进程中。它的职责包括:
AMS的核心职责:
├── Activity管理:启动、暂停、恢复、销毁、Task管理
├── Service管理:启动、绑定、解绑、停止
├── Broadcast管理:注册、注销、分发广播
├── ContentProvider管理:启动、发布、获取
├── 进程管理:创建进程、进程优先级、进程回收
├── Task管理:最近任务列表、Task栈管理
└── ANR检测:超时检测、错误处理
2
3
4
5
6
7
8
可以说,AMS是Android框架层的"大脑",几乎所有的组件行为都要经过AMS的调度和授权。
# 1.3 从系统启动看AMS的地位
在系统启动过程中,SystemServer启动后会创建一系列系统服务,AMS是最先被创建的核心服务之一:
// SystemServer.java
private void startBootstrapServices() {
// AMS是最先启动的服务之一
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
// 设置系统服务管理器
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
// 设置安装器
mActivityManagerService.setInstaller(installer);
// ... 其他服务依赖AMS
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AMS在所有系统服务中最先启动,因为后续的PMS、WMS等服务都需要依赖AMS来管理进程和组件。
# 02.AMS的整体架构设计
# 2.1 核心类关系
AMS的架构设计涉及多个核心类,理解它们的关系是理解AMS的基础:
AMS核心类关系:
┌─────────────────────────────────────────────┐
│ ActivityManagerService │
│ ┌─────────────────────────────────────────┐ │
│ │ ActivityTaskManagerService (ATMS) │ │
│ │ ├── ActivityStartController │ │
│ │ ├── ActivityStarter │ │
│ │ ├── RootWindowContainer │ │
│ │ │ ├── DisplayContent │ │
│ │ │ │ ├── TaskDisplayArea │ │
│ │ │ │ │ ├── Task │ │
│ │ │ │ │ │ └── ActivityRecord │ │
│ │ └── ClientLifecycleManager │ │
│ └─────────────────────────────────────────┘ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ ActiveServices │ │BroadcastQueue │ │
│ │ ├── ServiceRecord│ │├── BroadcastRecord│ │
│ │ └── ConnectionRec│ │└── ReceiverList │ │
│ └──────────────────┘ └──────────────────┘ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ ContentProviderHlp│ │ProcessList │ │
│ │ ├── ProviderInfo │ │├── ProcessRecord │ │
│ │ └── ContentProvRec│ │└── UidRecord │ │
│ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────┘
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
这里有个重要的设计演变:在Android 10之前,Activity的管理逻辑全部在AMS中;Android 10之后,Activity相关的逻辑被拆分到了ATMS(ActivityTaskManagerService)中。
# 2.2 核心数据结构
AMS中每种组件都有对应的Record类来描述:
// ActivityRecord:描述一个Activity实例
class ActivityRecord extends WindowToken {
final ActivityInfo info; // 组件信息
final ComponentName mActivityComponent; // 组件名
int mUserId; // 用户ID
Task task; // 所属的Task
ProcessRecord app; // 所属进程
ActivityState mState; // 当前生命周期状态
boolean finishing; // 是否正在finish
boolean visible; // 是否可见
ResultInfo resultTo; // 返回结果的目标
}
// ServiceRecord:描述一个Service实例
class ServiceRecord extends Binder {
final ServiceInfo serviceInfo; // 组件信息
final ComponentName name; // 组件名
ProcessRecord app; // 所属进程
boolean startRequested; // 是否已start
int lastStartId; // 最后一次startId
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections; // 绑定连接
}
// BroadcastRecord:描述一次广播分发
class BroadcastRecord extends Binder {
final Intent intent; // 广播Intent
final ProcessRecord callerApp; // 发送者进程
final List receivers; // 接收者列表
int nextReceiver; // 下一个待分发的接收者
long dispatchTime; // 分发时间
}
// ContentProviderRecord:描述一个ContentProvider实例
class ContentProviderRecord implements ComponentName.WithComponentName {
final ProviderInfo info; // 组件信息
final ComponentName name; // 组件名
ProcessRecord proc; // 所属进程
int externalProcessNoHandleCount; // 外部引用计数
ArrayList<ContentProviderConnection> connections; // 连接列表
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 2.3 Binder通信架构
应用进程与AMS之间通过Binder进行通信。这里采用了典型的Proxy-Stub模式:
应用进程 SystemServer进程
┌──────────────┐ ┌──────────────────┐
│ Application │ │ AMS │
│ │ Binder IPC │ │
│ IActivityMgr │◄──────────────────►│ IActivityMgr │
│ .Proxy │ │ .Stub │
│ │ │ │
│ IAppThread │ │ IAppThread │
│ .Stub │◄──────────────────►│ .Proxy │
│(ActivityThrd)│ │(AppThreadProxy) │
└──────────────┘ └──────────────────┘
2
3
4
5
6
7
8
9
10
11
注意这里有两条Binder通道:
- 应用→AMS:通过IActivityManager的Proxy,应用请求AMS执行操作
- AMS→应用:通过IApplicationThread的Proxy,AMS通知应用执行组件生命周期
# 03.AMS的启动与初始化流程
# 3.1 创建AMS实例
AMS在SystemServer的startBootstrapServices阶段创建:
// ActivityManagerService.java
public ActivityManagerService(Context systemContext,
ActivityTaskManagerService atm) {
// 1.获取系统上下文
mContext = systemContext;
// 2.获取主线程Handler
mHandlerThread = new ServiceThread("ActivityManager",
THREAD_PRIORITY_FOREGROUND, false);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
// 3.创建广播队列
// 前台广播超时时间10秒
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", foreConstants, false);
// 后台广播超时时间60秒
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", backConstants, true);
// 分时广播队列
mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
"offload", offloadConstants, true);
// 4.创建Service管理器
mServices = new ActiveServices(this);
// 5.创建ContentProvider管理器
mCpHelper = new ContentProviderHelper(this, true);
// 6.创建进程列表
mProcessList = new ProcessList();
// 7.初始化OOM调节器
mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 3.2 注册系统服务
AMS创建完成后,需要注册到ServiceManager中:
// SystemServer.java
private void startBootstrapServices() {
// ...创建AMS
// 注册到ServiceManager
mActivityManagerService.setSystemProcess();
}
// ActivityManagerService.java
public void setSystemProcess() {
// 注册AMS到ServiceManager
ServiceManager.addService(Context.ACTIVITY_SERVICE, this,
true, DUMP_FLAG_PRIORITY_CRITICAL);
// 注册其他相关服务
ServiceManager.addService("procstats", mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
ServiceManager.addService("cpuinfo", new CpuBinder(this));
// 创建SystemServer的ProcessRecord
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
ProcessRecord app = mProcessList.newProcessRecordLocked(info,
info.processName, false, 0, null);
app.setPersistent(true);
app.setPid(MY_PID);
app.getWindowProcessController().setPid(MY_PID);
mPidsSelfLocked.put(app);
mProcessList.updateLruProcessLocked(app, false, null);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 3.3 systemReady阶段
当所有系统服务初始化完成后,AMS进入systemReady阶段,这是启动用户应用的起点:
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
synchronized (this) {
// 阶段1:准备工作
mSystemReady = true;
// 杀掉在AMS准备好之前启动的异常进程
removeProcessLocked(false, false, "system ready");
}
// 阶段2:执行回调,通知其他服务AMS已就绪
if (goingCallback != null) goingCallback.run();
synchronized (this) {
// 阶段3:启动持久性进程
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
// 阶段4:启动Home Activity(Launcher)
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
// 阶段5:发送开机广播
broadcastIntentLocked(null, null, null,
new Intent(Intent.ACTION_BOOT_COMPLETED),
null, null, 0, null, null, null, ...);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 04.Activity的管理机制
# 4.1 Activity启动的AMS侧处理
当应用调用startActivity时,请求通过Binder到达AMS,AMS内部的处理流程如下:
startActivity请求到达AMS后的处理链:
ATMS.startActivity()
└── ActivityStarter.execute()
├── 1.resolveIntent() - 解析Intent,确定目标Activity
├── 2.resolveActivity() - 获取ActivityInfo
├── 3.权限检查
│ ├── checkStartAnyActivityPermission()
│ ├── shouldAbortBackgroundActivityStart() - 后台启动限制
│ └── interceptWithConfirmCredentialsIfNeeded()
├── 4.startActivityUnchecked()
│ ├── computeLaunchingTaskFlags() - 计算启动Flag
│ ├── getReusableTask() - 查找可复用Task
│ ├── computeSourceRootTask() - 计算源Task
│ └── recycleTask() 或 startNewTask()
└── 5.RootWindowContainer.resumeFocusedTasksTopActivities()
└── Task.resumeTopActivityUncheckedLocked()
└── TaskFragment.resumeTopActivity()
├── 暂停当前Activity
└── 启动目标Activity
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 4.2 Activity的状态管理
AMS通过ActivityRecord中的状态枚举来跟踪每个Activity的生命周期状态:
// ActivityRecord的状态定义
enum ActivityState {
INITIALIZING, // 初始化中
STARTED, // 已start
RESUMED, // 已resume(前台运行)
PAUSING, // 正在pause
PAUSED, // 已pause
STOPPING, // 正在stop
STOPPED, // 已stop
FINISHING, // 正在finish
DESTROYING, // 正在destroy
DESTROYED, // 已destroy
RESTARTING_PROCESS // 进程重启中
}
2
3
4
5
6
7
8
9
10
11
12
13
14
AMS通过ClientLifecycleManager和ClientTransaction机制来驱动Activity的状态转换:
// ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) {
final IApplicationThread client = transaction.getClient();
transaction.schedule(); // 通过Binder发送到应用进程
}
// 典型的状态转换事务
void resumeActivity(ActivityRecord r) {
final ClientTransaction clientTransaction = ClientTransaction.obtain(
r.app.getThread(), r.appToken);
// 添加回调(如onNewIntent)
clientTransaction.addCallback(NewIntentItem.obtain(
new ArrayList<>(r.newIntents)));
// 设置目标生命周期状态
clientTransaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(isForward));
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 4.3 Task和Back Stack管理
Task是Activity的容器,AMS通过Task来组织Activity栈:
Task管理结构(Android 12+):
RootWindowContainer
└── DisplayContent
└── TaskDisplayArea
├── Task (Root Task / 原ActivityStack)
│ ├── Task (Leaf Task)
│ │ ├── ActivityRecord (top)
│ │ ├── ActivityRecord
│ │ └── ActivityRecord (bottom)
│ └── Task (Leaf Task)
│ └── ActivityRecord
└── Task (Root Task)
└── Task (Leaf Task)
└── ActivityRecord
2
3
4
5
6
7
8
9
10
11
12
13
14
在Android 12中,原来的ActivityStack概念被统一为Task,形成了Root Task和Leaf Task的层级关系。这是一个重要的架构变化:
// Task.java (Android 12+)
class Task extends WindowContainer<WindowContainer> {
// Task的关键属性
int mTaskId; // Task唯一ID
Intent intent; // 启动此Task的Intent
int mCallingUid; // 创建者UID
String affinity; // Task亲和性
int mLaunchMode; // 启动模式
// 查找可复用的Activity
ActivityRecord findActivityInHistory(ComponentName cls) {
for (int i = getChildCount() - 1; i >= 0; i--) {
ActivityRecord r = getChildAt(i).asActivityRecord();
if (r != null && r.mActivityComponent.equals(cls)) {
return r;
}
}
return null;
}
// 将Activity移到顶部
void moveActivityToFront(ActivityRecord newTop) {
positionChildAt(POSITION_TOP, newTop, false);
updateEffectiveIntent();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 05.ActivityRecord与TaskRecord详解
# 5.1 ActivityRecord的完整字段
ActivityRecord是AMS中描述Activity最核心的数据结构,理解它的字段就理解了AMS如何看待一个Activity:
class ActivityRecord extends WindowToken {
// === 身份标识 ===
final ActivityInfo info; // 从Manifest解析的Activity信息
final ComponentName mActivityComponent; // 包名+类名
final String packageName; // 包名
private int mUserId; // 用户ID
final IBinder appToken; // 唯一标识token
// === 启动信息 ===
final Intent intent; // 启动Intent
int launchMode; // 启动模式
int mLaunchFlags; // 启动Flag
ActivityRecord resultTo; // startActivityForResult的返回目标
int requestCode; // 请求码
// === 运行状态 ===
ProcessRecord app; // 宿主进程
Task task; // 所属Task
ActivityState mState; // 生命周期状态
boolean finishing; // 是否正在finish
boolean mVisibleRequested; // 是否请求可见
boolean mOccludesParent; // 是否遮挡父容器
// === 状态保存 ===
Bundle icicle; // onSaveInstanceState保存的数据
PersistableBundle persistentState; // 持久化状态
boolean mHaveState; // 是否有保存的状态
// === 时间记录 ===
long createTime; // 创建时间
long lastVisibleTime; // 最后可见时间
long pauseTime; // pause时间
long launchTickTime; // 启动计时
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 5.2 启动模式的Task影响
不同的启动模式会影响AMS对Task的操作方式:
四种启动模式在AMS中的Task行为:
standard(标准模式):
Task-A: [Activity1, Activity2]
启动Activity2 →
Task-A: [Activity1, Activity2, Activity2'] // 新实例入栈
singleTop(栈顶复用):
Task-A: [Activity1, Activity2]
启动Activity2 →
Task-A: [Activity1, Activity2] // 复用栈顶,调用onNewIntent
启动Activity1 →
Task-A: [Activity1, Activity2, Activity1'] // 不在栈顶,创建新实例
singleTask(栈内复用):
Task-A: [Activity1, Activity2, Activity3]
启动Activity1 →
Task-A: [Activity1] // 复用Activity1,上面的全部出栈(clearTop)
singleInstance(单实例):
Task-A: [Activity1, Activity2]
启动Activity3(singleInstance) →
Task-A: [Activity1, Activity2]
Task-B: [Activity3] // 独占一个Task,Task中只有它
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
AMS中实现启动模式的关键逻辑:
// ActivityStarter.java
private Task getReusableTask() {
// singleTask和singleInstance需要查找可复用的Task
if (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK != 0
|| isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)) {
// 在所有Task中查找匹配affinity的Task
Task intentTask = mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);
if (intentTask != null) {
// 找到了可复用的Task
if (isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)) {
// 需要清除Task中目标Activity之上的所有Activity
ActivityRecord top = intentTask.performClearTaskLocked(
mStartActivity, mLaunchFlags);
if (top != null) {
// 复用已有实例,发送onNewIntent
top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
mStartActivity.launchStackId);
}
}
return intentTask;
}
}
return null;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 5.3 最近任务列表管理
AMS还负责管理"最近任务"列表,这是用户按下"最近任务"键看到的界面:
// RecentTasks.java
class RecentTasks {
// 最近任务列表
private final ArrayList<Task> mTasks = new ArrayList<>();
// 添加任务到最近列表
void add(Task task) {
// 检查是否需要移除重复的任务
int removeIndex = findRemoveIndexForAddTask(task);
if (removeIndex >= 0) {
mTasks.remove(removeIndex);
}
// 裁剪列表大小
trimForTaskLocked(task, true);
// 添加到列表顶部
mTasks.add(0, task);
// 通知任务列表变化
notifyTaskAdded(task);
}
// 获取最近任务列表(供Launcher显示)
ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(
int maxNum, int flags, boolean getTasksAllowed,
int userId, int callingUid) {
ArrayList<ActivityManager.RecentTaskInfo> res = new ArrayList<>();
for (int i = 0; i < mTasks.size(); i++) {
Task task = mTasks.get(i);
// 过滤检查...
res.add(createRecentTaskInfo(task, true));
if (res.size() >= maxNum) break;
}
return new ParceledListSlice<>(res);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 06.Service的管理与生命周期
# 6.1 Service管理的核心类
Service的管理由AMS中的ActiveServices类负责:
// ActiveServices.java
public final class ActiveServices {
final ActivityManagerService mAm;
// 所有已启动的Service,按用户分组
final SparseArray<ArrayMap<ComponentName, ServiceRecord>> mServiceMap
= new SparseArray<>();
// 等待重启的Service列表
final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<>();
// 已销毁正在等待清理的Service
final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<>();
// 待处理的Service启动请求
final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>();
// 前台Service通知
final ArrayMap<ServiceRecord, Long> mForegroundServiceNotifications = new ArrayMap<>();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 6.2 startService的完整流程
当应用调用startService(intent)时,经过以下处理链:
startService完整流程:
应用进程 SystemServer进程
ContextImpl.startService(intent)
│
└── AMP.startService() ──Binder──► AMS.startService()
│
└── ActiveServices.startServiceLocked()
│
├── 1.retrieveServiceLocked()
│ └── 解析Intent,查找或创建ServiceRecord
│
├── 2.权限检查
│ ├── 后台启动限制(Android 8.0+)
│ └── 前台Service类型检查(Android 12+)
│
├── 3.startServiceInnerLocked()
│ ├── 如果进程已启动:
│ │ └── sendServiceArgsLocked()
│ │ └── AT.scheduleServiceArgs()
│ │ └── Service.onStartCommand()
│ │
│ └── 如果进程未启动:
│ └── mAm.startProcessLocked()
│ └── 进程创建后回调
│ └── realStartServiceLocked()
│
└── 4.realStartServiceLocked()
├── AT.scheduleCreateService()
│ └── Service.onCreate()
├── sendServiceArgsLocked()
│ └── Service.onStartCommand()
└── 如果是前台Service
└── 设置前台通知超时
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
关键代码:
// ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service,
String resolvedType, int callingPid, int callingUid,
boolean fgRequired, String callingPackage, int userId) {
// 1.查找ServiceRecord
ServiceLookupResult res = retrieveServiceLocked(service, null,
resolvedType, callingPackage, callingPid, callingUid, userId,
true, callerFg, false, false);
ServiceRecord r = res.record;
// 2.Android 8.0后台启动限制
if (!r.startRequested && !fgRequired) {
final int allowed = mAm.getAppStartModeLOSP(r.appInfo.uid,
r.packageName, r.appInfo.targetSdkVersion, callingPid, false, false, false);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
// 后台应用不允许启动后台Service
return null;
}
}
// 3.记录启动请求
r.startRequested = true;
r.lastActivity = SystemClock.uptimeMillis();
r.pendingStarts.add(new ServiceRecord.StartItem(r, false,
r.makeNextStartId(), service, neededGrants, callingUid));
// 4.执行实际启动
return startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 6.3 Service的后台限制演进
这是一个典型的技术演变过程,体现了Android对后台管理的不断收紧:
Service后台限制的演进:
Android 6.0:Doze模式,待机时限制Service
└── 疑惑:为什么设备静止时Service还在运行浪费电量?
└── 答案:引入Doze,设备静止时延迟Service
Android 8.0(重大变更):后台Service限制
└── 疑惑:为什么应用退到后台还能通过Service持续运行?
└── 答案:应用进入后台数分钟后,系统停止其后台Service
└── 替代方案:使用JobScheduler或WorkManager
Android 12.0:前台Service限制
└── 疑惑:开发者滥用前台Service绕过后台限制
└── 答案:限制后台启动前台Service
└── 新增前台Service类型声明要求
Android 14.0:更严格的前台Service类型
└── 疑惑:前台Service类型声明不够细化
└── 答案:必须声明具体的foregroundServiceType
└── 每种类型有对应的权限要求
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 07.Service的启动与绑定原理
# 7.1 bindService的流程
bindService比startService更复杂,因为涉及到连接管理:
// ActiveServices.java
int bindServiceLocked(IApplicationThread caller, IBinder token,
Intent service, String resolvedType, IServiceConnection connection,
int flags, String callingPackage, int userId) {
// 1.获取调用者信息
final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller);
ActivityRecord activity = null;
if (token != null) {
activity = ActivityRecord.isInAnyTask(token);
// 如果是从Activity绑定,Service生命周期与Activity关联
}
// 2.查找ServiceRecord
ServiceLookupResult res = retrieveServiceLocked(service, null,
resolvedType, callingPackage, callingPid, callingUid, userId,
true, callerFg, isBindExternal, allowInstant);
ServiceRecord s = res.record;
// 3.创建连接记录
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity, connection,
flags, clientLabel, clientIntent, callerApp.uid, callerApp.processName);
// 4.保存连接关系
IBinder binder = connection.asBinder();
s.addConnection(binder, c);
b.connections.add(c);
callerApp.connections.add(c);
// 5.启动Service(如果尚未启动)
if ((flags & Context.BIND_AUTO_CREATE) != 0) {
bringUpServiceLocked(s, service.getFlags(), callerFg, false, false);
}
// 6.如果Service已经绑定过,直接回调onServiceConnected
if (s.app != null && b.intent.received) {
c.conn.connected(s.name, b.intent.binder, false);
// 如果是rebind
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
}
return 1;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 7.2 连接关系的数据结构
AMS中Service的连接关系用多个类来维护:
bindService连接关系图:
ServiceRecord (Service端)
└── ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
└── IntentBindRecord (按Intent分组)
├── Intent requestedIntent
├── IBinder binder // Service返回的IBinder
├── boolean received // 是否已收到onBind返回值
└── ArrayMap<ProcessRecord, AppBindRecord> apps
└── AppBindRecord (按进程分组)
├── ProcessRecord client // 客户端进程
├── ServiceRecord service // Service
└── ArraySet<ConnectionRecord> connections
└── ConnectionRecord (单个连接)
├── IServiceConnection conn // 回调接口
├── ActivityRecord activity // 绑定的Activity
└── int flags // 绑定标志
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 7.3 Service的ANR检测
AMS会为Service的关键操作设置超时检测:
// ActiveServices.java
void serviceDoneExecutingLocked(ServiceRecord r, int type,
int startId, int res) {
// 取消超时检测
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
}
private void scheduleServiceTimeoutLocked(ProcessRecord proc) {
// 前台Service超时20秒,后台Service超时200秒
long timeout = proc.mServices.shouldExecServicesFg()
? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT;
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG, proc);
mAm.mHandler.sendMessageDelayed(msg, timeout);
}
// 超时处理
void serviceTimeout(ProcessRecord proc) {
// 收集ANR信息
ANRHelper.appNotResponding(proc, null,
"executing service " + timeout.shortInstanceName);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
超时时间定义:
- 前台Service:
onCreate、onStartCommand、onBind等操作超时时间为 20秒 - 后台Service:超时时间为 200秒
# 08.BroadcastReceiver的注册与分发
# 8.1 动态注册的实现
动态注册广播接收者时,AMS会维护注册信息:
// ActivityManagerService.java
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission,
int userId, int flags) {
synchronized (this) {
// 1.获取或创建ReceiverList
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
mRegisteredReceivers.put(receiver.asBinder(), rl);
}
// 2.创建BroadcastFilter
BroadcastFilter bf = new BroadcastFilter(filter, rl,
callerPackage, permission, callingUid, userId,
instantApp, visibleToInstantApps);
// 3.添加到IntentResolver中
rl.add(bf);
mReceiverResolver.addFilter(bf);
// 4.检查是否有粘性广播需要立即分发
ArrayList<Intent> allSticky = null;
if (stickyIntents != null) {
for (Intent intent : stickyIntents) {
if (filter.match(intent) >= 0) {
if (allSticky == null) allSticky = new ArrayList<>();
allSticky.add(intent);
}
}
}
// 5.分发粘性广播
if (allSticky != null) {
for (Intent intent : allSticky) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, ...);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}
return sticky;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 8.2 广播分发的队列机制
AMS使用不同的广播队列处理不同类型的广播:
// BroadcastQueue的核心结构
class BroadcastQueue {
// 并行广播列表(同时发给所有接收者)
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
// 有序广播列表(按优先级依次分发)
final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>();
// 等待分发的广播
BroadcastRecord mPendingBroadcast = null;
// 超时时间
final long mTimeoutPeriod; // 前台10秒,后台60秒
}
2
3
4
5
6
7
8
9
10
11
12
13
14
AMS中有三个广播队列:
广播队列设计:
┌──────────────────────────────────────────┐
│ BroadcastQueue │
├──────────────────────────────────────────┤
│ mFgBroadcastQueue(前台广播) │
│ 超时:10秒 │
│ 用途:FLAG_RECEIVER_FOREGROUND标记的广播│
├──────────────────────────────────────────┤
│ mBgBroadcastQueue(后台广播) │
│ 超时:60秒 │
│ 用途:普通广播 │
├──────────────────────────────────────────┤
│ mOffloadBroadcastQueue(分时广播) │
│ 超时:60秒 │
│ 用途:系统分流的广播 │
└──────────────────────────────────────────┘
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 8.3 sendBroadcast的完整流程
// ActivityManagerService.java
final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage,
String callerFeatureId, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions,
int appOp, Bundle bOptions, boolean ordered, boolean sticky,
int callingPid, int callingUid, int realCallingUid,
int realCallingPid, int userId) {
intent = new Intent(intent);
// 1.处理特殊系统广播
final boolean isProtectedBroadcast = AppGlobals.getPackageManager()
.isProtectedBroadcast(action);
// 一些广播只有系统进程能发送
// 2.处理粘性广播
if (sticky) {
// 保存到粘性广播列表
ArrayList<Intent> list = mStickyBroadcasts.get(userId).get(action);
if (list == null) {
list = new ArrayList<>();
mStickyBroadcasts.get(userId).put(action, list);
}
list.add(new Intent(intent));
}
// 3.收集接收者
// 3.1 静态注册的接收者
List<ResolveInfo> receivers = AppGlobals.getPackageManager()
.queryIntentReceivers(intent, resolvedType, pmFlags, userId).getList();
// 3.2 动态注册的接收者
List<BroadcastFilter> registeredReceivers = mReceiverResolver
.queryIntent(intent, resolvedType, false, userId);
// 4.分发并行广播(动态注册的接收者)
if (!ordered && registeredReceivers.size() > 0) {
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, ...);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
registeredReceivers = null;
}
// 5.合并并排序有序广播接收者
// 将静态接收者和剩余动态接收者合并,按优先级排序
int NT = registeredReceivers != null ? registeredReceivers.size() : 0;
int it = 0;
for (int i = 0; i < receivers.size(); i++) {
// 按priority插入动态接收者
while (it < NT && registeredReceivers.get(it).getPriority()
>= receivers.get(i).priority) {
receivers.add(i, registeredReceivers.get(it));
it++;
}
}
// 6.分发有序广播
if (receivers.size() > 0) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, ...);
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 09.广播的有序与并行分发机制
# 9.1 并行广播分发
并行广播会同时发送给所有接收者,不需要等待每个接收者处理完成:
// BroadcastQueue.java
private void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
// 先处理并行广播
while (mParallelBroadcasts.size() > 0) {
BroadcastRecord r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
final int N = r.receivers.size();
for (int i = 0; i < N; i++) {
Object target = r.receivers.get(i);
// 直接发送给所有接收者,不等待返回
deliverToRegisteredReceiverLocked(r,
(BroadcastFilter) target, false, i);
}
// 所有接收者都发送完毕
addBroadcastToHistoryLocked(r);
}
// 再处理有序广播...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 9.2 有序广播分发
有序广播按优先级逐个分发,每个接收者处理完才分发给下一个:
// BroadcastQueue.java - 有序广播处理
private void processNextOrderedBroadcastLocked() {
// 获取当前正在处理的有序广播
BroadcastRecord r = mOrderedBroadcasts.get(0);
// 检查是否超时
if (mPendingBroadcastTimeoutMessage) {
long now = SystemClock.uptimeMillis();
if (now > r.dispatchTime + mTimeoutPeriod) {
// 超时处理
broadcastTimeoutLocked(false);
}
}
// 获取下一个接收者
int recIdx = r.nextReceiver++;
Object nextReceiver = r.receivers.get(recIdx);
if (nextReceiver instanceof BroadcastFilter) {
// 动态注册的接收者,直接分发
BroadcastFilter filter = (BroadcastFilter) nextReceiver;
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
// 设置超时
setBroadcastTimeoutLocked(mTimeoutPeriod);
} else {
// 静态注册的接收者,可能需要启动进程
ResolveInfo info = (ResolveInfo) nextReceiver;
if (app != null && app.thread != null) {
// 进程已存在,直接分发
processCurBroadcastLocked(r, app);
} else {
// 进程不存在,需要先启动进程
r.curApp = mService.startProcessLocked(targetProcess, ...);
mPendingBroadcast = r;
mPendingBroadcastRecvIndex = recIdx;
}
// 设置超时
setBroadcastTimeoutLocked(mTimeoutPeriod);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 9.3 广播超时与ANR
有序广播的超时处理机制:
// BroadcastQueue.java
final void broadcastTimeoutLocked(boolean suppressAlarm) {
if (suppressAlarm) {
mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this);
}
// 获取当前广播
BroadcastRecord r = mOrderedBroadcasts.get(0);
// 判断是否真的超时(可能因为系统繁忙导致误报)
long now = SystemClock.uptimeMillis();
if (now < r.dispatchTime + mTimeoutPeriod * 2) {
// 还有容忍空间,重新设置超时
setBroadcastTimeoutLocked(r.dispatchTime + mTimeoutPeriod - now);
return;
}
// 确认超时,记录ANR
if (r.curApp != null) {
mHandler.post(new AppNotResponding(r.curApp,
"Broadcast of " + r.intent.toString()));
}
// 跳过当前接收者,继续处理下一个
finishReceiverLocked(r, r.resultCode, r.resultData,
r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 10.ContentProvider的启动与管理
# 10.1 ContentProvider的安装时机
ContentProvider是四大组件中最特殊的一个,它在应用进程启动时就会被安装,早于Activity:
应用进程启动后的初始化顺序:
AMS.attachApplication()
│
├── 1.bindApplication()
│ └── ActivityThread.handleBindApplication()
│ ├── 创建Application
│ ├── 安装ContentProvider ← 在Application.onCreate()之前!
│ │ └── installContentProviders()
│ │ └── 逐个安装Provider
│ │ ├── installProvider()
│ │ │ ├── 反射创建Provider实例
│ │ │ └── Provider.onCreate()
│ │ └── AMS.publishContentProviders()
│ │ └── 通知AMS Provider已就绪
│ └── Application.onCreate() ← 注意:在Provider之后
│
├── 2.启动等待中的Activity
├── 3.启动等待中的Service
└── 4.分发等待中的Broadcast
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
为什么ContentProvider要最先安装?因为其他组件在运行过程中可能需要通过ContentProvider获取数据。
# 10.2 AMS中的Provider管理
// ContentProviderHelper.java
class ContentProviderHelper {
final ActivityManagerService mService;
// 所有已发布的Provider,按authority索引
final ProviderMap mProviderMap;
// 等待Provider发布的请求
final ArrayList<ContentProviderRecord> mLaunchingProviders = new ArrayList<>();
// 获取ContentProvider
ContentProviderHolder getContentProvider(IApplicationThread caller,
String callingPackage, String name, int userId, boolean stable) {
// 1.查找已发布的Provider
ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
if (cpr != null && cpr.proc != null) {
// Provider已经运行
if (checkContentProviderPermission(cpr, callingUid, userId) == null) {
// 增加引用计数
conn = incProviderCountLocked(r, cpr, token, callingUid,
callingPackage, callingTag, stable);
return cpr.newHolder(conn, false);
}
}
// 2.Provider未运行,需要启动其进程
if (cpr == null) {
cpr = mProviderMap.getProviderByClass(comp, userId);
}
if (cpr == null) {
// 从PMS获取Provider信息
ProviderInfo pi = AppGlobals.getPackageManager()
.resolveContentProvider(name, flags, userId);
cpr = new ContentProviderRecord(mService, pi, ...);
}
// 3.启动Provider所在的进程
final int N = mLaunchingProviders.size();
boolean launched = false;
for (int i = 0; i < N; i++) {
if (mLaunchingProviders.get(i) == cpr) {
launched = true; // 已经在启动中
break;
}
}
if (!launched) {
mLaunchingProviders.add(cpr);
// 启动进程
ProcessRecord proc = mService.startProcessLocked(
cpr.info.processName, cpr.appInfo, ...);
}
// 4.等待Provider发布(阻塞调用线程)
synchronized (cpr) {
while (cpr.provider == null) {
cpr.wait(CONTENT_PROVIDER_WAIT_TIMEOUT);
}
}
return cpr.newHolder(conn, false);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 10.3 Provider的引用计数
AMS通过引用计数来管理ContentProvider的生命周期:
// ContentProviderHelper.java
ContentProviderConnection incProviderCountLocked(ProcessRecord r,
ContentProviderRecord cpr, IBinder externalProcessToken,
int callingUid, String callingPackage, String callingTag,
boolean stable) {
if (r != null) {
// 查找已有连接
for (int i = 0; i < r.conProviders.size(); i++) {
ContentProviderConnection conn = r.conProviders.get(i);
if (conn.provider == cpr) {
// 增加引用计数
if (stable) {
conn.stableCount++;
conn.numStableIncs++;
} else {
conn.unstableCount++;
conn.numUnstableIncs++;
}
return conn;
}
}
// 创建新连接
ContentProviderConnection conn = new ContentProviderConnection(cpr, r, callingPackage);
if (stable) {
conn.stableCount = 1;
} else {
conn.unstableCount = 1;
}
cpr.connections.add(conn);
r.conProviders.add(conn);
return conn;
}
// 外部进程引用
cpr.addExternalProcessHandleLocked(externalProcessToken, callingUid, callingTag);
return null;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
当所有引用都被释放时,AMS可能会决定停止Provider所在的进程。stable引用和unstable引用的区别在于:stable引用释放会导致调用者进程被杀死(如果Provider进程崩溃),而unstable引用不会。
# 11.ContentProvider的跨进程数据共享
# 11.1 数据传输机制
ContentProvider跨进程数据共享的效率是个关键问题。对于query操作返回的Cursor,Android使用了共享内存优化:
ContentProvider query数据传输机制:
客户端进程 Provider进程
ContentResolver.query()
│
└── IContentProvider.query() ──Binder──► ContentProvider.query()
│
└── 返回Cursor
│
CursorWindow ◄──────────────────────── CursorWindow
(共享内存映射) (共享内存分配)
CursorWindow底层使用Ashmem(匿名共享内存),
通过Binder传递文件描述符实现零拷贝数据共享。
2
3
4
5
6
7
8
9
10
11
12
13
14
// CursorWindow.java
public class CursorWindow extends SQLiteClosable implements Parcelable {
// 底层使用Native SharedMemory
private long mWindowPtr; // native CursorWindow指针
// 默认窗口大小2MB
private static final int DEFAULT_WINDOW_SIZE = 2 * 1024 * 1024;
// 创建CursorWindow时分配共享内存
public CursorWindow(String name) {
mWindowPtr = nativeCreate(name, DEFAULT_WINDOW_SIZE);
}
// 通过Parcel序列化时,传递的是共享内存的文件描述符
@Override
public void writeToParcel(Parcel dest, int flags) {
nativeWriteToParcel(mWindowPtr, dest);
// 内部传递Ashmem的fd,而不是复制数据
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 11.2 批量操作优化
对于insert/update/delete等写操作,ContentProvider提供了批量操作接口来减少IPC次数:
// ContentProviderNative.java
public ContentProviderResult[] applyBatch(String callingPkg,
String authority, ArrayList<ContentProviderOperation> operations) {
// 单次Binder调用执行多个操作
// 比逐个调用insert/update/delete效率高得多
ContentProviderResult[] results = new ContentProviderResult[operations.size()];
for (int i = 0; i < operations.size(); i++) {
ContentProviderOperation operation = operations.get(i);
results[i] = operation.apply(this, results, i);
}
return results;
}
2
3
4
5
6
7
8
9
10
11
12
13
# 11.3 ContentProvider的权限模型
AMS在ContentProvider的访问控制中起关键作用:
// ContentProviderHelper.java
String checkContentProviderPermission(ProviderInfo cpi, int callingPid,
int callingUid, int userId) {
// 1.检查是否是同一应用(同UID免检)
if (UserHandle.isSameApp(callingUid, cpi.applicationInfo.uid)) {
return null; // 通过
}
// 2.检查exported属性
if (!cpi.exported) {
return "not exported from uid " + cpi.applicationInfo.uid;
}
// 3.检查读写权限
if (cpi.readPermission != null) {
if (mService.checkPermission(cpi.readPermission, callingPid, callingUid)
== PackageManager.PERMISSION_GRANTED) {
return null; // 有读权限
}
}
if (cpi.writePermission != null) {
if (mService.checkPermission(cpi.writePermission, callingPid, callingUid)
== PackageManager.PERMISSION_GRANTED) {
return null; // 有写权限
}
}
// 4.检查URI权限授予
// grantUriPermission允许临时授予特定URI的访问权限
// 5.检查path-level权限
PathPermission[] pps = cpi.pathPermissions;
if (pps != null) {
// 检查path级别的细粒度权限
}
return "requires " + cpi.readPermission + " or " + cpi.writePermission;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 12.进程管理与优先级调度
# 12.1 ProcessRecord详解
AMS为每个应用进程维护一个ProcessRecord:
class ProcessRecord implements WindowProcessListener {
// === 进程标识 ===
final ApplicationInfo info; // 应用信息
final String processName; // 进程名
int pid; // 进程ID
int uid; // 用户ID
IApplicationThread thread; // 应用进程的Binder接口
// === 进程状态 ===
int mCurProcState; // 当前进程状态
int mCurAdj; // 当前OOM_adj值
int mSetAdj; // 已设置的OOM_adj值
int mCurCapability; // 当前能力
boolean mKilledByAm; // 是否被AMS杀死
// === 组件持有 ===
final PackageList pkgList; // 加载的包
final ArrayList<ActivityRecord> activities; // Activity列表
final ArraySet<ServiceRecord> services; // Service列表
final ArraySet<ServiceRecord> executingServices; // 正在执行的Service
final ArrayList<ConnectionRecord> connections; // Service连接
final ArrayList<ContentProviderRecord> pubProviders; // 发布的Provider
final ArrayList<ContentProviderConnection> conProviders; // Provider连接
final ArraySet<BroadcastRecord> curReceivers; // 当前正在处理的广播
// === 进程管理辅助 ===
long lastActivityTime; // 最后活跃时间
long lastPssTime; // 最后PSS采样时间
long curRawAdj; // 原始adj
boolean hasActivities; // 是否有Activity
boolean hasServices; // 是否有Service
boolean hasClientActivities; // 是否有客户端Activity
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 12.2 进程优先级体系
Android将进程分为多个优先级等级,AMS根据进程持有的组件和状态来计算优先级:
进程优先级等级(从高到低):
优先级 adj值范围 说明
─────────────────────────────────────────────────
NATIVE_ADJ -1000 系统原生进程(init、zygote等)
SYSTEM_ADJ -900 SystemServer进程
PERSISTENT_ADJ -800 持久性进程(电话、蓝牙等)
PERSISTENT_SER -700 持久性进程绑定的Service
FOREGROUND_APP 0 前台进程(正在与用户交互)
VISIBLE_APP 100 可见进程(有可见Activity)
PERCEPTIBLE_APP 200 可感知进程(播放音乐等)
PERCEPTIBLE_LOW 250 低可感知(后台音频捕获等)
BACKUP_APP 300 备份进程
HEAVY_WEIGHT 400 重量级进程
SERVICE 500 服务进程(有启动的Service)
HOME 600 Home进程(Launcher)
PREVIOUS_APP 700 上一个前台进程
SERVICE_B 800 B类服务进程
CACHED_APP 900+ 缓存进程(后台,无活跃组件)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
AMS计算进程优先级的核心逻辑在OomAdjuster中:
// OomAdjuster.java
private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval) {
// 1.最高优先级:前台进程
if (app == topApp) {
adj = ProcessList.FOREGROUND_APP_ADJ;
procState = PROCESS_STATE_TOP;
}
// 2.检查是否在执行Instrumentation
if (app.getActiveInstrumentation() != null) {
adj = ProcessList.FOREGROUND_APP_ADJ;
procState = PROCESS_STATE_FOREGROUND_SERVICE;
}
// 3.检查是否接收广播
if (app.mReceivers.numberOfCurReceivers() > 0) {
adj = ProcessList.FOREGROUND_APP_ADJ;
}
// 4.检查Service
for (ServiceRecord s : app.mServices.getRunningServices()) {
if (s.isForeground) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = PROCESS_STATE_FOREGROUND_SERVICE;
}
// 检查Service的客户端进程优先级
for (ConnectionRecord cr : s.getConnections()) {
ProcessRecord client = cr.binding.client;
// 如果客户端优先级高,提升Service进程优先级
int clientAdj = client.mCurRawAdj;
if (clientAdj < adj) {
adj = Math.max(clientAdj, ProcessList.FOREGROUND_APP_ADJ);
}
}
}
// 5.检查ContentProvider
for (ContentProviderRecord cpr : app.pubProviders.values()) {
for (ContentProviderConnection conn : cpr.connections) {
ProcessRecord client = conn.client;
int clientAdj = client.mCurRawAdj;
if (clientAdj < adj) {
adj = clientAdj + 1;
}
}
}
// 6.缓存进程
if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
// 根据LRU位置分配不同的cached adj
}
app.mCurRawAdj = adj;
return true;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 13.OOM_adj算法与进程回收
# 13.1 OOM_adj更新时机
OomAdjuster不是持续运行的,而是在特定事件触发时更新:
触发OOM_adj更新的事件:
├── Activity状态变化
│ ├── onResume(进入前台)
│ ├── onPause/onStop(离开前台)
│ └── onDestroy(销毁)
├── Service状态变化
│ ├── startService / bindService
│ ├── stopService / unbindService
│ └── startForeground / stopForeground
├── Broadcast状态变化
│ ├── 开始处理广播
│ └── 广播处理完成
├── ContentProvider状态变化
│ ├── 获取Provider引用
│ └── 释放Provider引用
└── 进程状态变化
├── 进程创建
├── 进程死亡
└── 前台应用切换
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 13.2 进程回收策略
当系统内存不足时,LMKD(Low Memory Killer Daemon)根据AMS设置的adj值决定回收哪些进程:
// ProcessList.java
void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
// 根据屏幕大小动态计算各级别的内存阈值
float scaleMem = ((float)(mTotalMemMb - 350)) / (700 - 350);
// 各级别的最低内存阈值(页数)
int[] mOomMinFree = new int[]{
minfree_adj, // FOREGROUND_APP
minfree_abs / 2, // VISIBLE_APP
minfree_abs / 2 + ..., // PERCEPTIBLE_APP
minfree_abs, // BACKUP_APP
minfree_abs * 3 / 2, // CACHED_APP_MIN
minfree_abs * 2, // CACHED_APP_MAX
};
// 写入LMKD
if (write) {
writeLmkd(buf, null);
}
}
// 与LMKD通信
private boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
// 通过socket与lmkd进程通信
// 传递adj阈值和内存水位线
try {
sLmkdOutputStream.write(buf.array(), 0, buf.position());
} catch (IOException ex) {
// ...
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 13.3 缓存进程的LRU管理
AMS维护一个LRU(最近最少使用)列表来管理缓存进程:
// ProcessList.java
final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<>();
// 更新LRU位置
void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
ProcessRecord client) {
final boolean hasActivity = app.hasActivities || app.hasClientActivities;
final boolean hasService = false;
// 从列表中移除
int lrui = mLruProcesses.lastIndexOf(app);
if (lrui >= 0) {
mLruProcesses.remove(lrui);
}
// 根据是否有Activity和Service决定插入位置
if (hasActivity) {
// 有Activity的进程放在列表末尾(最不容易被杀)
int N = mLruProcesses.size();
mLruProcesses.add(N, app);
} else if (hasService) {
// 有Service的进程放在Activity之前
mLruProcesses.add(mLruProcessServiceStart, app);
mLruProcessServiceStart++;
} else {
// 什么都没有的进程放在最前面(最容易被杀)
mLruProcesses.add(0, app);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
LRU列表的结构:
mLruProcesses 列表结构:
Index: 0 1 2 ... serviceStart ... activityStart ... N-1
[纯缓存进程] [有Service的进程] [有Activity的进程]
←──────────────────────────────────────────────────→
最先被杀 最后被杀
2
3
4
5
# 14.AMS中的ANR检测机制
# 14.1 ANR检测的整体设计
AMS负责检测三种类型的ANR:
AMS的ANR检测类型:
1. InputDispatch ANR(输入事件ANR)
超时时间:5秒
触发条件:Input事件分发到应用后5秒内未处理完成
检测者:InputDispatcher(Native层)→ AMS
2. BroadcastReceiver ANR
超时时间:前台10秒,后台60秒
触发条件:onReceive方法执行超时
检测者:BroadcastQueue → AMS
3. Service ANR
超时时间:前台20秒,后台200秒
触发条件:Service生命周期方法执行超时
检测者:ActiveServices → AMS
4. ContentProvider ANR
超时时间:发布超时
触发条件:Provider发布超过CONTENT_PROVIDER_PUBLISH_TIMEOUT
检测者:AMS
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 14.2 Input ANR检测流程
Input ANR的检测涉及Native层和Java层的协作:
// InputDispatcher.cpp (Native层)
// 检测窗口是否超时未响应
nsecs_t InputDispatcher::getDispatchingTimeoutLocked(
const sp<IBinder>& token) {
sp<InputWindowHandle> window = getWindowHandleLocked(token);
if (window != null) {
return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
}
return DEFAULT_INPUT_DISPATCHING_TIMEOUT; // 5秒
}
// 超时后通知Java层
void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
// 通过JNI回调到Java层
mPolicy->notifyNoFocusedWindowAnr(token);
}
// InputManagerCallback.java (Java层)
public void notifyNoFocusedWindowAnr(InputApplicationHandle application) {
mService.mAnrController.notifyAppUnresponsive(
application, "Input dispatching timed out");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 14.3 ANR信息收集
当ANR发生时,AMS负责收集诊断信息:
// AnrHelper.java
void appNotResponding(ProcessRecord anrProcess, String activityShortComponentName,
ApplicationInfo aInfo, String annotation) {
// 将ANR处理放入工作线程
mAnrRecords.add(new AnrRecord(anrProcess, activityShortComponentName,
aInfo, annotation));
// 执行ANR处理
synchronized (mAnrRecords) {
AnrRecord r = mAnrRecords.get(0);
r.appNotResponding(isFirst);
}
}
// ProcessRecord里的ANR处理
void appNotResponding(String activityShortComponentName,
ApplicationInfo aInfo, String annotation) {
// 1.记录ANR的基本信息
long anrTime = SystemClock.uptimeMillis();
// 2.收集CPU使用情况
processCpuTracker.update();
// 3.Dump线程堆栈到traces.txt
File tracesFile = ActivityManagerService.dumpStackTraces(
firstPids, nativePids, extraPids, null);
// 4.记录到EventLog
EventLog.writeEvent(EventLogTags.AM_ANR, userId, pid, processName,
info.flags, annotation);
// 5.构建ANR报告
StringBuilder info = new StringBuilder();
info.append("ANR in ").append(processName);
info.append("\nPID: ").append(pid);
info.append("\nReason: ").append(annotation);
info.append("\n");
// 6.CPU使用信息
info.append("CPU usage from ").append(anrDuration).append("ms ago:\n");
processCpuTracker.printCurrentLoad(info);
info.append("CPU usage from ").append(delta).append("ms to now:\n");
processCpuTracker.printCurrentState(info, anrTime);
// 7.弹出ANR对话框
mService.mUiHandler.sendMessage(Message.obtain(mService.mUiHandler,
ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG,
new AppNotRespondingDialog.Data(app, activityShortComponentName, info)));
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 15.AMS与WMS的协作关系
# 15.1 协作架构
AMS和WMS是Android系统中关系最密切的两个系统服务。AMS管理组件生命周期,WMS管理窗口显示:
AMS与WMS协作关系图:
AMS侧 WMS侧
┌─────────────────┐ ┌─────────────────┐
│ ActivityRecord │◄──────────────►│ WindowState │
│ (组件生命周期) │ │ (窗口状态) │
│ │ │ │
│ Task │◄──────────────►│ Task (Window侧) │
│ (任务管理) │ │ (窗口层级) │
│ │ │ │
│ RootWindowContain│ == 共享 == │ RootWindowContain│
│ er (Activity树) │ │ er (Window树) │
└─────────────────┘ └─────────────────┘
在Android 10+中,AMS和WMS共享了RootWindowContainer,
Activity和Window的管理被统一到了同一个树形结构中。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 15.2 Activity启动时的AMS-WMS协作
Activity启动过程中AMS与WMS的交互:
1. AMS决定启动Activity
│
2. AMS创建ActivityRecord
└── 同时在WindowContainer树中创建对应节点
│
3. AMS通知应用创建Activity
│
4. 应用调用setContentView
│
5. ViewRootImpl.setView()
└── WMS.addWindow() ← 创建WindowState
├── 分配Surface
└── 计算窗口层级
│
6. WMS通知SurfaceFlinger创建Layer
│
7. View绘制完成
│
8. WMS执行窗口动画
└── 通知AMS Activity已可见
│
9. AMS更新ActivityRecord状态
└── 回调onResume
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 15.3 转场动画的协调
Activity切换时的转场动画需要AMS和WMS紧密协作:
// Activity转场动画的协调流程
class Transition {
// 1.AMS侧:准备转场
void prepareTransition(ActivityRecord opening, ActivityRecord closing) {
// 通知WMS准备动画
mWmService.prepareAppTransition(transit);
// 设置参与转场的窗口
opening.setVisibility(true);
closing.setVisibility(false);
}
// 2.WMS侧:执行动画
void executeTransition() {
// 获取动画参数
Animation openAnim = loadAnimation(opening);
Animation closeAnim = loadAnimation(closing);
// 在SurfaceFlinger中执行动画
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.setAlpha(opening.getSurface(), animatedAlpha);
t.apply();
}
// 3.动画完成回调
void onTransitionFinished() {
// WMS通知AMS动画完成
mAtmService.onTransitionFinished();
// AMS可以继续后续的生命周期
closing.setState(STOPPED);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 15.4 从Android 10看架构统一
Android 10是AMS-WMS关系的分水岭。在此之前,AMS中有ActivityStack/TaskRecord管理Activity,WMS中有DisplayContent/WindowState管理窗口。两者通过AppWindowToken关联。
Android 10+将两者统一到WindowContainer层次结构中:
Android 10+的统一WindowContainer树:
RootWindowContainer
├── DisplayContent (屏幕)
│ ├── DisplayArea (显示区域)
│ │ ├── TaskDisplayArea
│ │ │ ├── Task (Root Task = 原ActivityStack)
│ │ │ │ └── Task (Leaf Task = 原TaskRecord)
│ │ │ │ └── ActivityRecord (= 原AppWindowToken)
│ │ │ │ └── WindowState (窗口)
│ │ │ └── Task
│ │ │ └── ...
│ │ └── TaskDisplayArea
│ │ └── ...
│ ├── DisplayArea (输入法区域)
│ │ └── ImeContainer
│ │ └── WindowState (输入法窗口)
│ └── DisplayArea (壁纸区域)
│ └── WallpaperWindowToken
│ └── WindowState (壁纸窗口)
└── DisplayContent (第二屏幕)
└── ...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
这种统一设计的好处是Activity生命周期和窗口显示不再需要跨两个服务同步,减少了竞态条件和状态不一致的问题。
# 16.AMS的演进与ATMS重构
# 16.1 AMS的历史演进
AMS从Android 1.0开始就存在,经历了多次重大重构:
AMS的演进历史:
Android 1.0 ~ 4.4:
└── 单体AMS,所有逻辑都在ActivityManagerService中
└── 问题:代码量巨大(2万+行),职责混杂
Android 5.0 (Lollipop):
└── 引入ActivityStackSupervisor
└── 分离部分Activity栈管理逻辑
└── 支持多用户
Android 7.0 (Nougat):
└── 多窗口支持
└── ActivityStack结构变化,支持分屏
└── 引入pinned stack(画中画)
Android 8.0 (Oreo):
└── 后台限制
└── 后台Service限制
└── 广播限制(大量隐式广播不再发送给静态注册者)
Android 10 (Q):
└── 重大重构:ATMS拆分
└── Activity管理逻辑从AMS拆分到ATMS
└── AMS保留进程管理、Service、Broadcast、Provider
└── WindowContainer统一化
Android 12 (S):
└── Task统一
└── ActivityStack被废弃,统一为Task
└── Root Task + Leaf Task层级
Android 13 (T):
└── 广播队列现代化
└── BroadcastQueue重写为BroadcastQueueModernImpl
└── 支持更灵活的分发策略
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 16.2 ATMS拆分的设计思想
Android 10将Activity相关逻辑拆分到ATMS的核心原因:
拆分前(单体AMS)的问题:
┌─────────────────────────────────────┐
│ ActivityManagerService │
│ ┌───────────┐ ┌───────────────┐ │
│ │ Activity │ │ Process │ │
│ │ Management │ │ Management │ │
│ ├───────────┤ ├───────────────┤ │
│ │ Service │ │ Broadcast │ │
│ │ Management │ │ Management │ │
│ ├───────────┤ ├───────────────┤ │
│ │ Provider │ │ Window相关 │ │
│ │ Management │ │ 逻辑 │ │
│ └───────────┘ └───────────────┘ │
│ 代码超过3万行 │
│ 锁竞争严重 │
│ Activity和Window逻辑耦合 │
└─────────────────────────────────────┘
拆分后的结构:
┌──────────────────┐ ┌────────────────────┐
│ AMS │ │ ATMS │
│ ├── Process │ │ ├── Activity │
│ ├── Service │ │ │ Management │
│ ├── Broadcast │ │ ├── Task │
│ └── Provider │ │ │ Management │
│ │ │ ├── ActivityStarter │
│ 负责进程和非 │ │ └── 与WMS深度集成 │
│ Activity组件 │ │ │
│ │ │ 负责Activity和 │
│ │ │ Window Container │
└──────────────────┘ └────────────────────┘
↕ 通过AtmInternal和AmInternal相互调用
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// ATMS和AMS的交互接口
// AMS调用ATMS
class ActivityTaskManagerInternal {
abstract void onProcessAdded(WindowProcessController proc);
abstract void onProcessRemoved(String name, int uid);
abstract boolean attachApplication(WindowProcessController wpc);
abstract void startHomeOnAllDisplays(int userId, String reason);
}
// ATMS调用AMS
class ActivityManagerInternal {
abstract void trimApplications();
abstract void killProcess(String processName, int uid, String reason);
abstract int startProcess(String processName, ApplicationInfo info, ...);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 16.3 未来趋势
从AMS的演进可以看到几个趋势:
趋势一:职责拆分。从单体AMS到AMS+ATMS的拆分,遵循单一职责原则。未来可能会进一步拆分Service管理、Broadcast管理为独立服务。
趋势二:后台管控加强。从Android 8.0的后台Service限制到Android 14的前台Service类型限制,后台执行能力在持续收紧。替代方案是WorkManager和JobScheduler。
趋势三:窗口与组件统一。Android 10将Activity和Window统一到WindowContainer体系,这一趋势在不断深化。未来的多屏、折叠屏等场景将受益于此。
趋势四:安全与隐私增强。后台Activity启动限制(Android 10+)、前台Service类型声明(Android 12+)等,都是从AMS层面加强安全控制。
# 17.总结与技术思考
# 17.1 核心要点回顾
AMS与四大组件管理的核心要点:
1. AMS是Android系统的"大脑"
└── 运行在SystemServer进程中
└── 通过Binder为所有应用提供组件管理服务
2. 每种组件都有对应的Record和管理者
├── Activity → ActivityRecord → ATMS
├── Service → ServiceRecord → ActiveServices
├── Broadcast → BroadcastRecord → BroadcastQueue
└── Provider → ContentProviderRecord → ContentProviderHelper
3. 进程管理是AMS的另一个核心职责
├── ProcessRecord记录进程状态
├── OomAdjuster计算进程优先级
└── LMKD根据adj值回收进程
4. ANR检测贯穿所有组件
├── Input事件ANR(5秒)
├── Broadcast ANR(10/60秒)
├── Service ANR(20/200秒)
└── Provider发布ANR
5. AMS-WMS协作管理Activity和窗口
└── Android 10+统一到WindowContainer体系
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 17.2 面试高频问题
问题:AMS和ATMS的区别?
- AMS管理进程、Service、Broadcast、ContentProvider
- ATMS管理Activity和Task,与WMS深度集成
- 两者通过AmInternal和AtmInternal相互调用
问题:为什么ContentProvider最先被安装?
- ContentProvider在Application.onCreate之前安装
- 因为其他组件可能在初始化时就需要访问ContentProvider的数据
- 典型场景:三方SDK在Application.onCreate中通过ContentProvider自动初始化
问题:AMS如何决定杀死哪个进程?
- AMS通过OomAdjuster计算每个进程的adj值
- adj值基于进程持有的组件和它们的状态
- Service绑定关系会传递优先级(进程依赖链)
- LMKD根据adj值和内存水位线执行实际的进程杀死
# 17.3 学习建议
理解AMS需要关注三个层面:
- 接口层面:应用如何通过Context/PackageManager与AMS交互
- 协议层面:Binder通信协议、ClientTransaction协议
- 实现层面:AMS内部的Record、Queue、Adjuster等核心数据结构和算法
建议按照"启动→管理→回收"的主线来学习:从组件如何被启动,到AMS如何跟踪组件状态,最后到进程如何被优先级调度和回收,形成完整的认知链条。