引言
Android 系统通过 ActivityManagerService(AMS)统一管理四大组件的生命周期和交互。虽然都是通过 Binder 与 AMS 通信,但四大组件在交互方式、生命周期管理、进程优先级等方面存在显著差异。本文将分析这些差异,帮助开发者更好地理解 Android 系统架构。
四大组件与 AMS 交互对比表
| 组件 | 启动/注册模式 | AMS数据结构 | 生命周期管理 | 进程交互 | 优先级管理 | 主要特点 |
|---|---|---|---|---|---|---|
| Activity | 显式/隐式 Intent | ActivityStack/Task/ActivityRecord | 栈式管理,AMS 严格控制状态转换 | 强绑定,每个状态变化都通知 AMS | 前台/可见进程,由任务栈位置决定 | 用户交互界面,AMS 管理窗口、输入焦点 |
| Service | startService()/bindService() | ServiceRecord/ConnectionRecord | 启动/绑定两套生命周期,AMS 协调进程优先级 | 启动/停止/绑定/解绑时交互 | 动态变化(前台/可见/服务进程) | 后台执行,AMS 管理进程保活和绑定关系 |
| BroadcastReceiver | 静态注册/动态注册 | BroadcastQueue/ReceiverList/BroadcastRecord | 瞬时执行,无持久状态,AMS 管理分发队列 | 发送/接收时交互,执行完即结束 | 无独立优先级,依赖宿主进程 | 事件驱动,AMS 处理权限和有序分发 |
| ContentProvider | 自动发布 | ProviderMap/ContentProviderRecord | 持久存在,与应用进程同生命周期 | 查询/插入/更新/删除时交互 | 依赖宿主进程,但 AMS 管理访问权限 | 数据共享,AMS 路由 URI 和权限控制 |
详细交互机制分析
1. Activity 与 AMS 交互
核心交互流程
js
// 启动流程
应用进程 → AMS: startActivity(intent) // 启动请求
AMS → 应用进程: scheduleLaunchActivity() // 调度启动
应用进程 → AMS: activityPaused() // 状态同步
AMS → 其他应用进程: schedulePauseActivity() // 暂停其他Activity
AMS → 应用进程: scheduleResumeActivity() // 恢复当前Activity
AMS 管理要点:
- 维护 ActivityStack 和 Task 的任务栈结构
- 控制 Back Stack 回退逻辑
- 管理 Activity 的启动模式(standard、singleTop 等)
- 处理多窗口模式下的可见性
- 协调 Activity 转场动画
进程优先级: Activity 所在进程优先级由其在任务栈中的位置决定:
- 前台 Activity → 前台进程(adj=0)
- 可见但不在前台 → 可见进程(adj=100)
- 完全不可见 → 缓存进程(adj=900+)
2. Service 与 AMS 交互
启动服务流程:
js
应用进程 → AMS: startService(intent)
AMS → 应用进程: scheduleCreateService() → scheduleServiceArgs()
// 绑定服务流程
应用进程 → AMS: bindService(intent, conn, flags)
AMS → 服务端进程: scheduleBindService()
AMS → 客户端进程: 返回 IBinder
AMS 管理要点:
- 维护 ServiceRecord 记录服务状态
- 管理 ConnectionRecord 绑定关系
- 控制服务进程的优先级
- 处理前台服务通知
- 协调跨进程服务绑定
进程优先级动态变化:
java
// AMS 动态调整服务进程优先级
if (service.isForeground) {
// 前台服务,优先级最高
process.setAdj(ProcessList.FOREGROUND_APP_ADJ); // 0
} else if (process.hasVisibleActivities()) {
// 绑定到可见Activity,优先级较高
process.setAdj(ProcessList.VISIBLE_APP_ADJ); // 100
} else if (process.hasServices()) {
// 只有服务,无可见组件
process.setAdj(ProcessList.SERVICE_ADJ); // 500
} else {
// 无活跃组件,优先级最低
process.setAdj(ProcessList.CACHED_APP_MIN_ADJ); // 900+
}
3. BroadcastReceiver 与 AMS 交互
注册和发送流程:
js
// 注册流程
应用进程 → AMS: registerReceiver(receiver, filter)
// 发送流程
应用进程 → AMS: sendBroadcast(intent)
AMS → 接收进程: scheduleReceiver() // 异步分发
// 执行完成后
接收进程 → AMS: 无回调,执行完即结束
AMS 管理要点:
- 维护广播队列(有序/无序)
- 处理粘性广播缓存
- 检查发送和接收权限
- 控制广播超时
- 管理进程优先级临时提升
广播执行特点:
- 瞬时执行,无生命周期状态维护
- AMS 不跟踪接收器执行状态
- 异步分发,可能延迟或丢弃
- 可并行执行多个无序广播
4. ContentProvider 与 AMS 交互
发布和查询流程:
js
/ 发布流程
应用进程 → AMS: publishContentProviders(providers)
// 查询流程
客户端进程 → AMS: getContentProvider(name)
AMS → 服务端进程: 无直接调用,返回已发布的Provider接口
客户端进程 → 服务端进程: 直接调用IContentProvider.query()
AMS 管理要点:
- 维护 ProviderMap 路由表
- 检查跨进程访问权限
- 管理 Provider 引用计数
- 处理 Provider 进程死亡
- 协调 URI 权限授权
数据共享模型:
js
// AMS 中的Provider路由
class ProviderMap {
// authority → ContentProviderRecord
ArrayMap<String, ContentProviderRecord> mProvidersByName;
// component → ContentProviderRecord
ArrayMap<ComponentName, ContentProviderRecord> mProvidersByClass;
}
// ContentProviderRecord
class ContentProviderRecord {
IContentProvider provider; // 真正的Provider接口
ProcessRecord app; // 所在进程
int externalProcessNo; // 外部进程引用计数
// 当引用计数为0时,AMS可通知进程清理Provider
}
跨进程通信差异
1. Binder 通信频率
js
// Activity: 高频通信
// 每个生命周期变化都要通信
onCreate() ↔ onCreate() 通知
onStart() ↔ onStart() 通知
onResume() ↔ onResume() 通知
onPause() ↔ onPause() 通知
onStop() ↔ onStop() 通知
onDestroy()↔ onDestroy() 通知
// Service: 中频通信
// 启动/停止/绑定/解绑时通信
onCreate() ↔ 启动时通信
onStartCommand() ↔ 每次启动通信
onBind() ↔ 绑定时通信
onUnbind() ↔ 解绑时通信
// Broadcast: 低频通信
// 注册/发送时通信
registerReceiver() ↔ 注册时通信
sendBroadcast() ↔ 发送时通信
// onReceive() 执行无需回调AMS
// ContentProvider: 按需通信
// 获取Provider时通信一次
getContentProvider() ↔ 获取时通信
// 后续操作直接与Provider进程通信
2. 数据传输量
js
// Activity: 大量数据
// 传递整个ActivityRecord,包含Intent、Options等
data.writeParcelable(activityRecord);
// Service: 中等数据
// 传递Intent和启动参数
data.writeParcelable(service);
data.writeInt(flags);
data.writeInt(startId);
// Broadcast: 小量数据
// 主要传递Intent
data.writeParcelable(intent);
// ContentProvider: 变长数据
// 传递URI和查询参数
data.writeParcelable(uri);
data.writeStringArray(projection);
data.writeString(selection);
data.writeStringArray(selectionArgs);
生命周期管理深度
1. Activity 生命周期(AMS 完全控制)
这个生命周期是没有设置configChanges参数。主要简单介绍一下AMS是如何参与到Activity的生命周期中的。设置了configChanges参数的有兴趣的可以单独搜索一下相关文档。 
2. Service 生命周期(AMS 部分控制)
js
// 启动式服务
AMS: 启动服务 → 应用: onCreate() → onStartCommand() → 运行
↓
AMS: 停止服务 → 应用: onDestroy()
// 绑定式服务
AMS: 绑定服务 → 应用: onCreate() → onBind() → 服务绑定
↓
AMS: 所有客户端解绑 → 应用: onUnbind() → onDestroy()
3. BroadcastReceiver 生命周期(AMS 不管理)
js
/ AMS只管理分发,不管理执行状态
AMS: 收到广播 → 查找接收器 → 分发到进程
应用进程: 创建Receiver实例 → onReceive() → 销毁实例
// 执行完毕即结束,无状态跟踪
4. ContentProvider 生命周期(与应用进程绑定)
js
/ Provider生命周期跟随应用进程
应用进程启动 → onCreate() → 运行
↓
应用进程死亡 → onDestroy()
// AMS只管理Provider的发布和引用
AMS: 发布Provider → 增加引用 → 减少引用 → 通知清理
AMS 中的调度策略
1. 优先级调度差异
js
// Activity调度:基于任务栈
ActivityStack.getNextActivityToResume() {
// 总是恢复栈顶Activity
return mActivities.get(mActivities.size() - 1);
}
// Service调度:基于进程状态
updateServiceProcessLocked(ServiceRecord sr) {
if (sr.isForeground) {
// 前台服务,保持进程存活
keepProcessAlive(sr.app);
} else if (sr.bindings.size() > 0) {
// 有绑定,适当保活
adjustProcessAdj(sr.app, ProcessList.SERVICE_ADJ);
}
}
// Broadcast调度:基于队列
BroadcastQueue.scheduleBroadcastsLocked() {
// 顺序处理队列中的广播
processNextBroadcast(true);
}
// ContentProvider调度:基于需求
getContentProviderImpl(name) {
// 按需启动Provider进程
if (provider == null) {
startProcessLocked(cpr.processName, ...);
}
}
2. 内存管理策略
js
// 四大组件的内存回收优先级
boolean shouldKillProcess(ProcessRecord app) {
// 计算进程重要性
int importance = calculateImportance(app);
// 判断标准(简化):
// 1. 有前台Activity的进程最后杀
// 2. 有可见Activity的进程次之
// 3. 有前台Service的进程再次
// 4. 有普通Service的进程
// 5. 有缓存Provider的进程
// 6. 只有BroadcastReceiver的进程最先杀
return importance < threshold;
}
总结
四大组件与 AMS 的交互体现了 Android 系统的分层设计:
- Activity - 用户界面层: AMS 严格管理,确保用户体验
- Service - 后台任务层: AMS 协调进程优先级,平衡性能
- BroadcastReceiver - 事件通信层: AMS 负责路由,解耦组件
- ContentProvider - 数据共享层: AMS 控制访问,保证安全
关键区别在于:
- 控制粒度: Activity 最细,Broadcast 最粗
- 状态管理: Activity 和 Service 有状态,Broadcast 无状态
- 进程影响: Activity 和前台 Service 可提升进程优先级
- 通信模式: Activity/Service 双向,Broadcast 单向,Provider 按需
AMS 作为系统协调者,针对不同组件的特性采用不同的管理策略,确保系统高效、稳定运行。