目录
  1. 1. 一、Activity 的工作过程
    1. 1.1. 1.1 完整调用链
    2. 1.2. 1.2 关键 Binder 接口
    3. 1.3. 1.3 进程不存在时的处理
    4. 1.4. 1.4 ActivityStarter:启动决策引擎
  2. 2. 二、Service 的工作过程
    1. 2.1. 2.1 startService 调用链
    2. 2.2. 2.2 ActiveServices——Service 的管理器
    3. 2.3. 2.3 ServiceRecord 数据结构
    4. 2.4. 2.4 bindService 与混合生命周期
  3. 3. 三、BroadcastReceiver 的工作过程
    1. 3.1. 3.1 广播注册(registerReceiver)
    2. 3.2. 3.2 广播发送(sendBroadcast)
    3. 3.3. 3.3 BroadcastQueue——双队列模型
    4. 3.4. 3.4 有序广播 vs 无序广播
    5. 3.5. 3.5 粘性广播(Sticky Broadcast,已废弃)
  4. 4. 四、ContentProvider 的工作过程
    1. 4.1. 4.1 Provider 的发布与获取
    2. 4.2. 4.2 ContentProviderHolder——跨进程传输的容器
    3. 4.3. 4.3 Transport——Provider 端的 Binder 实现
    4. 4.4. 4.4 CRUD 操作的完整链路
  5. 5. 五、四大组件的统一调度框架
  6. 6. 六、进程优先级与回收顺序
  7. 7. 七、核心面试题
    1. 7.1. 6.1 静态广播接收者的注册时机
    2. 7.2. 6.2 goAsync() 机制详解
    3. 7.3. 6.3 前台 Service 的限制演进
【吃透源码系列】之四大组件的工作过程

Android 四大组件(Activity、Service、BroadcastReceiver、ContentProvider)是应用开发的基础。它们的启动、运行和调度均由 AMS(及 ATMS)统一管理,通过 Binder IPC 与 App 进程通信。本文从源码角度系统地分析四大组件各自的工作过程,揭示其跨进程调度的核心机制。

一、Activity 的工作过程

1.1 完整调用链

App 进程: Activity.startActivity()
→ Instrumentation.execStartActivity()
→ ActivityTaskManager.getService().startActivity() // Binder

system_server: ATMS.startActivity()
→ ActivityStarter.execute()
→ ActivityStarter.startActivityUnchecked()
→ RootWindowContainer.resumeFocusedStacksTopActivities()
→ ActivityStack.startPausingLocked() // 暂停当前 Activity
→ ActivityStackSupervisor.startSpecificActivityLocked()

system_server → App 进程: ATMS.realStartActivityLocked() // Binder
→ ApplicationThread.scheduleTransaction()

App 进程: ActivityThread.handleLaunchActivity()
→ performLaunchActivity() // 创建 Activity,调 onCreate/onStart
→ handleResumeActivity() // 调 onResume

1.2 关键 Binder 接口

App 进程 → system_server: IActivityTaskManager.startActivity()(Android 10+)
system_server → App 进程: IApplicationThread.scheduleTransaction()(Android 10+ 统一为 ClientTransaction)

// App 端 AIDL
// frameworks/base/core/java/android/app/IActivityTaskManager.aidl
interface IActivityTaskManager {
int startActivity(...);
int startActivityAsUser(...);
boolean finishActivity(...);
}

// system_server 端 AIDL
// frameworks/base/core/java/android/app/IApplicationThread.aidl
interface IApplicationThread {
oneway void scheduleTransaction(in ClientTransaction transaction);
}

1.3 进程不存在时的处理

如果目标 Activity 所在进程尚未启动,AMS 通过 Zygote fork 新进程:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, ...) {
// 1. 检查是否有 Package 级别的进程错误
// 2. 通过 Socket 向 Zygote 发送 fork 请求
final Process.ProcessStartResult startResult = startProcess(...);
// Zygote fork 新进程后,新进程执行 ActivityThread.main()
// 3. 新进程通过 Binder 向 AMS attachApplication()
// 4. attachApplication() → AMS.realStartActivityLocked()
}

Zygote fork 的流程

AMS.startProcessLocked()
→ Process.start() // Java 层
→ ZygoteProcess.startViaZygote()
→ zygoteSendArgsAndGetResult() // 通过 Socket 发送参数到 Zygote

Zygote 进程:
ZygoteServer.runSelectLoop() 接收请求
→ ZygoteConnection.processOneCommand()
→ Zygote.forkAndSpecialize() // fork + 设置 UID/GID/seccomp

新进程:
RuntimeInit.applicationInit()
→ ActivityThread.main()
→ Looper.prepareMainLooper()
→ ActivityThread.attach(true, ...) ← Binder 向 AMS 注册
→ Looper.loop()

1.4 ActivityStarter:启动决策引擎

ActivityStarter 是 Activity 启动流程中最核心的决策类:

// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
class ActivityStarter {
int execute() {
// 1. 解析 Intent 和 flags
// 2. 确定目标 Task(targetStack)
// 3. 处理权限检查
// 4. 决策创建新 Activity 还是复用已有的
// 5. 管理 Task 和 ActivityRecord
}

// 核心决策方法
int startActivityUnchecked(...) {
// 计算 launch flags、Intent flags、ActivityInfo flags 的综合效果
// 决定:
// - 是否创建新 Task (NEW_TASK)
// - 是否清除顶层 Activity (CLEAR_TOP)
// - 是否复用已有实例 (SINGLE_TOP)
// - 复用哪个 Task (singleTask/singleInstance)
}
}

二、Service 的工作过程

2.1 startService 调用链

Service 有两种启动方式:startServicebindService。这里分析 startService:

App 进程: ContextWrapper.startService()
→ ContextImpl.startServiceCommon()
→ ActivityManager.getService().startService() // Binder

system_server: AMS.startService()
→ ActiveServices.startServiceLocked()
→ ActiveServices.bringUpServiceLocked()
→ ActiveServices.realStartServiceLocked()
→ app.thread.scheduleCreateService() // Binder

App 进程: ApplicationThread.scheduleCreateService()
→ ActivityThread.handleCreateService()
→ Service.onCreate()
→ Service.onStartCommand()

2.2 ActiveServices——Service 的管理器

ActiveServices 是 AMS 内部管理所有 Service 的核心类:

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
final ActivityManagerService mAm;

// 正在启动中的 Service
final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>();

// 按 userId → ServiceMap(再按包名 → ServiceRecord)组织
final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();

ServiceRecord retrieveServiceLocked(Intent service, ...) {
// 查找或创建 ServiceRecord
}

ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType, ...) {
// 1. 查找 ServiceRecord
ServiceRecord r = retrieveServiceLocked(service, ...);
// 2. 如果进程未启动,先启动进程 → bringUpServiceLocked
// 3. 如果进程已启动,直接 realStartServiceLocked
return r.name;
}
}

2.3 ServiceRecord 数据结构

// frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
final class ServiceRecord extends ComponentName implements ComponentName.WithComponentName {
final ActivityManagerService ams;
final ServiceInfo serviceInfo; // AndroidManifest 中定义的 ServiceInfo
final String packageName;
final String processName;
ProcessRecord app; // 运行的进程
boolean startRequested; // 是否调用了 startService
boolean stopIfKilled; // 进程被杀时是否停止
final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings;
int totalRestartCount;
int lastStartId;
long lastActivity; // 最后活跃时间
}

2.4 bindService 与混合生命周期

// bindService 的核心:跨进程传递 IBinder
// Service 端:
@Override
public IBinder onBind(Intent intent) {
return new LocalBinder(); // Binder 对象传递给调用方
}

// 调用方:
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// service 是一个 BinderProxy,代理 Service 端的 LocalBinder
}
@Override
public void onServiceDisconnected(ComponentName name) {}
};
bindService(intent, conn, Context.BIND_AUTO_CREATE);

三、BroadcastReceiver 的工作过程

3.1 广播注册(registerReceiver)

// App 进程:
// ContextWrapper.registerReceiver()
// → ContextImpl.registerReceiverInternal()
// → ActivityManager.getService().registerReceiver() // Binder
// ↓
// system_server: AMS.registerReceiver()
// → BroadcastQueue 中注册 BroadcastFilter(动态注册)
// ReceiverList rl = (ReceiverList) mRegisteredReceivers.get(receiver.asBinder());

// App 进程启动时,静态广播在 PKMS 扫描 AndroidManifest 时已注册,
// 不需要运行时再调用 registerReceiver

3.2 广播发送(sendBroadcast)

App 进程: Context.sendBroadcast(intent)
→ ActivityManager.getService().broadcastIntent() // Binder

system_server: AMS.broadcastIntent()
→ broadcastIntentLocked()
→ 根据 IntentFilter 匹配接收者(静态 + 动态)
→ BroadcastQueue.enqueueBroadcastLocked(r)
→ BroadcastQueue.processNextBroadcast()

两种情况:
A. 接收者进程已存在 → 直接 deliverToRegisteredReceiverLocked
→ performReceiveLocked() → app.thread.scheduleRegisteredReceiver() // Binder
B. 接收者进程不存在 → 先 startProcessLocked (fork),再发送

3.3 BroadcastQueue——双队列模型

// frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
public final class BroadcastQueue {
final ActivityManagerService mService;
final String mQueueName;
final long mTimeoutPeriod; // 超时时间(前台10秒,后台60秒)

// 无序广播队列(并行处理)
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
// 有序广播队列(串行处理)
BroadcastRecord mOrderedBroadcasts;

final void processNextBroadcast(boolean fromMsg) {
// 1. 处理并行广播(一次性发送给所有匹配接收者)
while (mParallelBroadcasts.size() > 0) {
BroadcastRecord r = mParallelBroadcasts.remove(0);
// 获取所有匹配的接收者
for (Object target : r.receivers) {
// 立即发送(通过 Binder 发给目标进程)
deliverToRegisteredReceiverLocked(r, target, ...);
}
}

// 2. 处理有序广播(依次发给每个接收者,前一个完成后才发下一个)
do {
if (mOrderedBroadcasts == null) return;

// 找到下一个该接收此广播的注册者(按 priority 排序)
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
while (r.nextReceiver < numReceivers) {
// 按 priority 顺序获取下一个接收者
Object nextReceiver = r.receivers.get(r.nextReceiver);
r.nextReceiver++;

// 通过 Binder 发送给目标进程
deliverToRegisteredReceiverLocked(r, nextReceiver, r.ordered);

if (r.resultAbort) {
// receive 设置了 abortBroadcast(),停止分发
r.receiver = null;
break; // 截断广播!
}
}
// 所有接收者都已通知,处理下一个有序广播
r = mOrderedBroadcasts;
} while (r != null);
}
}

前台广播队列超时 10 秒,后台广播队列超时 60 秒。如果接收者超时未返回,触发 ANR。

3.4 有序广播 vs 无序广播

无序广播(sendBroadcast):所有接收者同时收到,不能中断。
有序广播(sendOrderedBroadcast):按 priority 排序依次接收,前面的接收者可以通过 abortBroadcast() 截断广播。

3.5 粘性广播(Sticky Broadcast,已废弃)

// Android 5.0 (API 21) 废弃
sendStickyBroadcast(intent); // 已不推荐使用

粘性广播在发送后缓存,后续注册的接收者也能收到。但由于安全和内存原因(无限制缓存、任何应用都能读取),Google 在 API 21 废弃了此 API。

四、ContentProvider 的工作过程

4.1 Provider 的发布与获取

ContentProvider 在应用进程启动时(Application.onCreate 之前)就被安装和发布到 AMS:

App 进程启动:
ActivityThread.handleBindApplication()
→ installContentProviders() // 加载并初始化本进程声明的所有 Provider
→ AMS.publishContentProviders() // 将 Provider 的 Binder 注册到 AMS

其他 App 进程查询:
context.getContentResolver().query(uri)
→ ContentResolver.acquireProvider(uri) // 查找 Provider
→ ActivityManager.getService().getContentProvider() // Binder

AMS.getContentProvider()
→ 如果目标进程存在 → 返回 ContentProviderHolder(IContentProvider Binder)
→ 如果目标进程不存在 → 先 fork 进程,等 Provider 发布后再返回

4.2 ContentProviderHolder——跨进程传输的容器

// frameworks/base/core/java/android/app/ContentProviderHolder.java
public class ContentProviderHolder implements Parcelable {
public final ProviderInfo info;
public IContentProvider provider; // Binder 代理(Provider 端暴露的接口)
public IBinder connection; // 连接绑定的 Binder(用于死亡通知)
public boolean noReleaseNeeded; // 同进程时不需 release
}

4.3 Transport——Provider 端的 Binder 实现

每个 ContentProvider 在创建时,内部会创建一个 Transport 对象作为 Binder 服务端:

// frameworks/base/core/java/android/content/ContentProvider.java
public abstract class ContentProvider implements ContentInterface {

private Transport mTransport = new Transport();

class Transport extends ContentProviderNative {
@Override
public Cursor query(String callingPkg, Uri uri, ...) {
// 在 Provider 所在进程中执行
return ContentProvider.this.query(uri, projection, ...);
}
}
}

// frameworks/base/core/java/android/content/ContentProviderNative.java
abstract public class ContentProviderNative extends Binder
implements IContentProvider {
// Binder 实现的抽象类
}

4.4 CRUD 操作的完整链路

Client App:
getContentResolver().query(uri, ...)
→ ContentResolver.acquireProvider(uri) // 缓存或从 AMS 获取
→ IContentProvider.query() // Binder IPC

Provider App (Binder 线程池中的某个线程):
Transport.query() // ContentProviderNative.query 的 onTransact 分发
→ ContentProvider.query()
→ 返回 Cursor

Client App:
返回 CursorToBulkCursorAdapter (Binder proxy)
→ CursorWindow 通过 ashmem 跨进程共享查询结果
→ 后续 cursor.moveToNext() 等操作在本地 CursorWindow 中执行(无需 Binder IPC)

CursorWindow 的作用:减少跨进程的往返。Provider 端将多行查询结果写入共享内存(ashmem 或 memfd),客户端直接从这个共享区域读取。只有游标移出窗口时(如 moveToPosition 超出已加载行数),才触发新的 Binder IPC 获取下一批数据。

五、四大组件的统一调度框架

Android 10 引入 ClientTransactionClientLifecycleManager 统一了组件生命周期调度。AMS/ATMS 端构建 ClientTransaction 对象,包含多个 ClientTransactionItem,通过 IApplicationThread.scheduleTransaction() 发送到 App 进程执行。

// frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
public class ClientTransaction implements Parcelable, ObjectPoolItem {
private List<ClientTransactionItem> mActivityCallbacks; // 生命周期回调项
private ActivityLifecycleItem mLifecycleStateRequest; // 最终目标状态
private IApplicationThread mClient; // 目标进程

public void schedule() throws RemoteException {
mClient.scheduleTransaction(this); // Binder 调用
}
}

ClientTransactionItem 的子类

  • LaunchActivityItem — 启动 Activity
  • ResumeActivityItem — Resume Activity
  • PauseActivityItem — Pause Activity
  • StopActivityItem — Stop Activity
  • DestroyActivityItem — Destroy Activity
  • NewIntentItem — 处理新 Intent(onNewIntent)
  • ActivityConfigurationChangeItem — 配置变更

这背后的设计思想是:系统不应该直接告诉 App “你该到某状态了”,而是发送一组事务项,App 进程根据自身状态和事务项计算出最终状态并执行过渡。这减少了 App 端生命周期处理的复杂度。

六、进程优先级与回收顺序

Android 的 LMK(Low Memory Killer / lmkd)按以下优先级回收进程:

优先级(oom_adj) 说明 典型进程
-1000 系统进程 system_server
-900 ~ -800 持久化系统进程 PhoneApp, NFC
0 前台进程 正在交互的 Activity
100 可见进程 被 Dialog 覆盖的 Activity
200 可感知进程 运行前台 Service
300 服务进程 运行后台 Service
700 缓存进程(上层) 不可见但所需 Activity 仍在栈中
900 缓存进程(底层) 空进程、finish 的 Activity
906 缓存进程(终结) 最快被 LMK 杀死的进程
1000 已标记要杀死的进程 待回收

七、核心面试题

Q1:为什么 ContentProvider 的 onCreate 在 Application 的 onCreate 之前执行?

这是 Android 的设计约定。ContentProvider 可能被其他应用在 Application.onCreate 之前通过 getContentResolver().query() 访问。为了保证 ContentProvider 随时可用,系统在 Application.onCreate 之前就初始化了本进程声明的所有 ContentProvider。这对应用的启动性能有显著影响——如果定义了多个 Provider,每个 Provider 的 onCreate 都执行完后才轮到 Application.onCreate。这就是为什么 Firebase 等 SDK 的初始化从 ContentProvider 迁移到了其他方式(如 App Startup 库)。

Q2:有序广播和无序广播在系统实现层面最大的区别是什么?

在 AMS 端,无序广播对应的 BroadcastRecord 放入 mParallelBroadcasts 列表,一次性对所有匹配接收者发送。有序广播则放入 mOrderedBroadcasts 链表,依次发送给每个接收者,需要等待前一个接收者完成(BroadcastReceiver.goAsync()onReceive() 返回)后才发送给下一个。这个”等待”机制通过 BroadcastQueue.processNextBroadcast() 的循环实现——每次收到接收者的完成通知后才调用 processNextBroadcast() 继续分发。

Q3:startService 和 bindService 混用时,Service 的生命周期遵循什么规则?

当同时调用 startServicebindService 时,Service 的停止需要同时满足两个条件:调用了 stopService(或 stopSelf)且所有绑定都已解除。具体表现为:startService 使 Service 进入 started 状态(onStartCommand 回调),bindService 使 Service 进入 bound 状态(onBind 回调)。只有当 stopService 被调用且 unbindService 全部完成后,onDestroy 才会被调用。

Q4:ClientTransaction 统一调度相比 Android 9 之前的独立 Binder 调用有什么优势?

(1) 原子性:多个生命周期回调可以打包为一个事务,减少 Binder 往返次数。(2) 一致性:系统端构建事务后发送,App 端按事务描述执行——而不是系统端逐条发送指令,App 被动响应。(3) 可组合性:事务中可以灵活组合 callbacks 和最终状态请求,支持复杂的生命周期路径(如 Pause → Stop → Destroy 合并为一次事务)。(4) 代码清晰度:所有生命周期指令统一为一个入口(scheduleTransaction),而非分散在多个 AIDL 方法中。

Q5:Cursor 跨进程传输为什么使用 CursorWindow 而不是逐行 Binder 传递?

CursorWindow 使用共享内存(ashmem/memfd)传递查询结果,客户端的 cursor moveToNext 操作直接读取共享内存中的数据,无需 Binder IPC。如果逐行通过 Binder 传递,1000 行结果需要 1000 次 Binder 调用,每次至少一次上下文切换。而 CursorWindow 只需一次 Binder 调用传输 file descriptor,后续所有 cursor 操作都是在本地内存中完成,性能差异巨大(毫秒 vs 秒)。

6.1 静态广播接收者的注册时机

静态广播(在 AndroidManifest 中声明的 <receiver>)不需要运行时 registerReceiver。它们在 PKMS 扫描 APK 时被注册。注册流程:

PKMS 扫描 AndroidManifest
→ 解析 <receiver> 标签
→ 创建 ActivityInfo/ProviderInfo 对象(包含 IntentFilter)
→ 存入 ComponentResolver 的 mReceivers 中
→ 系统启动完成(BOOT_COMPLETED)后,所有静态接收者立即可接收广播

但从 Android 8.0 开始,大部分隐式广播不再发给静态接收者(Google 限制以减少后台进程唤醒)。仅少数白名单广播(如 BOOT_COMPLETED、LOCALE_CHANGED)依然对静态接收者生效。

6.2 goAsync() 机制详解

BroadcastReceiver.goAsync() 允许接收者在 onReceive 返回后继续处理广播:

public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final PendingResult pendingResult = goAsync();
// 在后台线程异步处理
new Thread(() -> {
// 处理耗时操作...
pendingResult.setResultCode(Activity.RESULT_OK);
pendingResult.finish(); // 必须调用,否则 AMS 超时后 ANR
}).start();
// onReceive 立即返回,但广播仍在处理中
}
}

goAsync() 返回的 PendingResult 包含一个 Binder token,AMS 通过这个 token 跟踪广播处理进度。如果 finish() 未在超时(前台 10 秒/后台 60 秒)内调用,AMS 触发 ANR。

6.3 前台 Service 的限制演进

Android 8.0 (API 26) 引入了前台 Service 的通知要求,后续版本持续收紧:

  • Android 8.0:startForegroundService() + 必须 5 秒内调用 startForeground(id, notification)
  • Android 9.0:需要 FOREGROUND_SERVICE 权限
  • **Android 10+**:后台启动前台 Service 受限(BOOT_COMPLETED 后不可用)
  • **Android 12+**:前台 Service 启动更受限制,新增 foregroundServiceType 声明(如 location、camera、microphone)
  • **Android 14+**:进一步要求前台 Service 必须有可见的用户界面或持续通知

这些限制通过 AMS 在 startServiceLocked 中检查,不满足条件则抛出 SecurityException 或 ForegroundServiceDidNotStartInTimeException。

AOSP 核心路径参考:

  • frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
  • frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
  • frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
  • frameworks/base/services/core/java/com/android/server/am/ContentProviderRecord.java
  • frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
  • frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
  • frameworks/base/core/java/android/app/ActivityThread.java
  • frameworks/base/core/java/android/app/ContextImpl.java
  • frameworks/base/core/java/android/content/ContentProvider.java
  • frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
打赏
  • 微信
  • 支付宝

评论