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)
interface IActivityTaskManager { int startActivity(...); }
interface IApplicationThread { oneway void scheduleTransaction(in ClientTransaction transaction); }
|
1.3 进程不存在时的处理
如果目标 Activity 所在进程尚未启动,AMS 通过 Zygote fork 新进程:
ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, ...) { final Process.ProcessStartResult startResult = startProcess(...); }
|
二、Service 的工作过程
2.1 startService 调用链
Service 有两种启动方式:startService 和 bindService。这里分析 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 的核心类:
public final class ActiveServices { final ActivityManagerService mAm;
final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>();
final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();
ServiceRecord retrieveServiceLocked(Intent service, ...) { }
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, ...) { ServiceRecord r = retrieveServiceLocked(service, ...); return r.name; } }
|
2.3 ServiceRecord 数据结构
final class ServiceRecord extends ComponentName implements ComponentName.WithComponentName { final ActivityManagerService ams; final ServiceInfo serviceInfo; final String packageName; final String processName; ProcessRecord app; boolean startRequested; boolean stopIfKilled; final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings; int totalRestartCount; int lastStartId; }
|
三、BroadcastReceiver 的工作过程
3.1 广播注册(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——双队列模型
public final class BroadcastQueue { final ActivityManagerService mService; final String mQueueName; final long mTimeoutPeriod;
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>(); BroadcastRecord mOrderedBroadcasts;
final void processNextBroadcast(boolean fromMsg) { while (mParallelBroadcasts.size() > 0) { ... }
do { r = mOrderedBroadcasts; deliverToRegisteredReceiverLocked(r, filter, r.ordered); } while (r == mOrderedBroadcasts); } }
|
前台广播队列超时 10 秒,后台广播队列超时 60 秒。如果接收者超时未返回,触发 ANR。
3.4 有序广播 vs 无序广播
无序广播(sendBroadcast):所有接收者同时收到,不能中断。
有序广播(sendOrderedBroadcast):按 priority 排序依次接收,前面的接收者可以通过 abortBroadcast() 截断广播。
四、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——跨进程传输的容器
public class ContentProviderHolder implements Parcelable { public final ProviderInfo info; public IContentProvider provider; public IBinder connection; public boolean noReleaseNeeded;
public ContentProviderHolder(ProviderInfo _info) { info = _info; } }
|
4.3 Transport——Provider 端的 Binder 实现
每个 ContentProvider 在创建时,内部会创建一个 Transport 对象作为 Binder 服务端:
public abstract class ContentProvider implements ContentInterface {
private Transport mTransport = new Transport();
class Transport extends ContentProviderNative { @Override public Cursor query(String callingPkg, Uri uri, ...) { return ContentProvider.this.query(uri, projection, ...); } } }
abstract public class ContentProviderNative extends Binder implements IContentProvider { }
|
4.4 CRUD 操作的完整链路
Client App: getContentResolver().query(uri, ...) → ContentResolver.acquireProvider(uri) → IContentProvider.query() // Binder IPC ↓ Provider App (Binder 线程池中的某个线程): Transport.query() // ContentProviderNative.query 的 onTransact 分发 → ContentProvider.query() → 返回 Cursor ↓ Client App: 返回 CursorToBulkCursorAdapter (Binder proxy) → SQLiteCursor 的实际操作通过 Binder 回到 Provider 进程的 BulkCursorToCursorAdaptor
|
五、四大组件的统一调度框架
Android 10 引入 ClientTransaction 和 ClientLifecycleManager 统一了组件生命周期调度。AMS/ATMS 端构建 ClientTransaction 对象,包含多个 ClientTransactionItem,通过 IApplicationThread.scheduleTransaction() 发送到 App 进程执行。
public class ClientTransaction implements Parcelable, ObjectPoolItem { private List<ClientTransactionItem> mActivityCallbacks; private ActivityLifecycleItem mLifecycleStateRequest; private IApplicationThread mClient;
public void schedule() throws RemoteException { mClient.scheduleTransaction(this); } }
|
这背后的设计思想是:系统不应该直接告诉 App “你该到某状态了”,而是发送一组事务项,App 进程根据自身状态和事务项计算出最终状态并执行过渡。这减少了 App 端生命周期处理的复杂度。
六、核心面试题
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() 返回)后才发送给下一个。这个”等待”机制通过 Handler 消息实现——每次发送后,设置一个超时定时器,接收者完成时移除定时器,超时则触发 ANR。
Q3:startService 和 bindService 混用时,Service 的生命周期遵循什么规则?
当同时调用 startService 和 bindService 时,Service 的停止需要同时满足两个条件:调用了 stopService(或 stopSelf)且所有绑定都已解除。具体表现为:startService 使 Service 进入 started 状态(onStartCommand 回调),bindService 使 Service 进入 bound 状态(onBind 回调)。只有当 stopService 被调用且 unbindService 全部完成后,onDestroy 才会被调用。
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/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