第3章:startActivity启动流程源码剖析:从AMS到ActivityRecord的完整链路
3.1 流程概述
startActivity 的启动过程远不止表面上的 Activity 跳转。从应用进程发起请求,通过 Binder 跨进程通信到达系统服务端 SystemServer 中的 ActivityManagerService(AMS),再由 AMS 执行权限校验、进程管理、任务栈管理、生命周期调度等一系列核心决策,最终生成一个代表本次启动目标的 ActivityRecord 对象。本章将带领你沿着这个路径,逐层剖析关键源码,掌握整个链路的骨架。
3.2 调用入口:Instrumentation.execStartActivity
无论在 Activity 中调用 startActivity(Intent),还是通过 Context.startActivity,最终都会集中到 Instrumentation 类的 execStartActivity 方法。这个方法是客户端侧向 AMS 发起请求的最后一站。
// frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder , Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
// 通过 ActivityManagerNative.getDefault() 获取 AMS 的 Binder 代理
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// 检查 result 并返回
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
关键链路节点:该方法内部通过 ActivityManagerNative.getDefault() —— 即 IActivityManager.Stub.asInterface(ServiceManager.getService("activity")) —— 获取 AMS 的 Binder 代理对象。随后调用的 startActivity 实际上已经跨入了 SystemServer 进程。
3.3 AMS 侧接收请求:startActivity→startActivityAsUser
Binder 驱动将请求序列化后传输到 SystemServer 进程,AMS 的 startActivity 方法被唤醒。该方法是整个流程的调度枢纽,它经过一系列参数检查和用户身份确认,最终调用内部的 startActivityAsUser。
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle options, int userId) {
// 检查调用进程是否有发起该 Intent 的权限
enforceNotIsolatedCaller("startActivityAsUser");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_NON_FULL, "startActivityAsUser", null);
// 此处进入 ActivityStarter 进行下一步决策
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
3.4 ActivityStarter:启动策略的决策引擎
ActivityStarter 内部维护了一套复杂的启动规则,包括 FLAG_ACTIVITY_NEW_TASK、taskAffinity、启动模式(launchMode)等。核心入口是 startActivityMayWait,该方法首先调用 PackageManagerService 解析 Intent。
// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
final int startActivityMayWait(...) {
...
// 1. Intent 解析,获取 ActivityInfo
ActivityInfo aInfo = resolveActivity(intent, rInfo, startFlags, profilerInfo);
if (aInfo == null) {
// 返回错误:ActivityNotFound
return ActivityManager.START_INTENT_NOT_RESOLVED;
}
// 2. 创建 ActivityRecord 前的参数准备
ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
...
// 3. 调用 startActivity 进入真正的决策与执行
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
false, componentSpecified, outRecord, activityOptions, inTask, ...);
return res;
}
经过解析后,ActivityStarter 会调用内部的 startActivity 方法(重载),在此方法中经过安全校验、进程存活检查、以及启动模式确认后,最终执行到 startActivityUnchecked 方法。该方法根据 Intent 的标志和 Activity 的启动模式,决定是将启动新 Activity、复用栈顶、还是入栈到 Existing 任务。
| 启动模式 | ActivityStarter 决策行为 | 常见影响 |
|---|---|---|
| Standard | 默认创建新实例,入栈到启动者的任务栈 | 可以多次创建相同 Activity |
| SingleTop | 如果目标 Activity 已是栈顶,则复用;否则创建新实例 | 避免栈顶重复打开 |
| SingleTask | 检查是否存在任务栈,存在则复用并清空栈上方的 Activity | 全局单例,启动时其他 Activity 会被出栈 |
| SingleInstance | 独立的任务栈,且整个栈只能有该 Activity | 独立于其他应用的栈结构 |
3.5 ActivityRecord 的诞生
ActivityRecord 是 AMS 中代表一个具体 Activity 实例的“元数据对象”,它封装了包名、类名、intent、、进程信息、任务栈信息、生命周期状态等所有必要数据。ActivityStarter 在 startActivityUnchecked 中通过 ActivityStackSupervisor 的 startActivityLocked 方法创建该对象。
// frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,
int _launchedFromUid, String _launchedFromPackage, Intent _intent,
String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
ActivityRecord _resultTo, String _resultWho, int _reqCode,
boolean _componentSpecified, ActivityRecord _sourceRecord,
ActivityStack _activityStack, ActivityOptions options, ActivityRecord _sourceRecord2) {
service = _service;
intent = _intent;
info = aInfo;
userId = UserHandle.getUserId(aInfo.applicationInfo.uid);
...
// 生成一个 32 位的唯一标识符 用于 Binder 通信
appToken = new (this);
...
}
appToken 字段,该字段是一个 Binder 对象,Activity 端通过 与 AMS 通信,AMS 通过 反查找到对应的 ActivityRecord。3.6 从 AMS 到目标进程:阶段小结与流程图
从应用程序调用 startActivity 到 AMS 内部创建 ActivityRecord,整个过程可以抽象为以下 6 个阶段。下图展示了这个完整的时序与核心节点。
3.7 完整调用链代码结构
以下是关键调用链路径,每个方法都落在对应类的内部。你可以使用 Android Studio 的 Show Call Hierarchy 快速验证这些调用关系。
客户端:
Instrumentation.execStartActivity()
→ ActivityManagerNative.getDefault().startActivity() // Binder 调用
↓ Binder 驱动
服务端:
ActivityManagerService.startActivity()
→ ActivityManagerService.startActivityAsUser()
→ ActivityStarter.startActivityMayWait()
→ ActivityStarter.startActivity() // 重载方法
→ ActivityStarter.startActivityUnchecked()
→ ActivityStackSupervisor.startActivityLocked()
→ new ActivityRecord(service, caller, intent, aInfo, ...)
startActivityMayWait 之前只解析出了 ActivityInfo,而真正的对象生成是在 startActivityUnchecked 处理完启动模式、任务栈复用逻辑之后,由 ActivityStackSupervisor 负责生成。3.8 调试与验证方法
你可以在 ActivityStackSupervisor.startActivityLocked 中打印日志,确认 ActivityRecord 创建时的详细信息:
// 添加调试日志(需在 userdebug 或 eng 版本下测试)
if (DEBUG_STACK) {
Slog.d(TAG, "Creating ActivityRecord: pkg=" + aInfo.packageName
+ ", cls=" + aInfo.name
+ ", userId=" + userId
+ ", resultTo=" + (resultTo != null ? resultTo.shortComponentName : "null")
+ ", callingPid=" + _caller.pid);
}
你也可以通过 dumpsys activity activities 命令实时查看当前系统中所有 ActivityRecord 的状态:
adb shell dumpsys activity activities | grep -E "ActivityRecord|Hist"
# 输出示例:
# * ActivityRecord{76c1b27 u0 com.example.app/.MainActivity t123}
# intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]}
# processName=com.example.app
# launchedFromUid=10123
# state=RESUMED
ActivityRecord 的 state 字段表明当前生命周期阶段(INITIALIZING → RESUMED ↔ PAUSED → STOPPED → DESTROYED)。通过监控 dumpsys 输出,你可以判断定制的边界控制逻辑是否在 ActivityRecord 创建之前或创建时被正确触发。
ActivityStarter.startActivityMayWait 执行 after PMS 解析但 before 创建 ActivityRecord 的阶段插入拦截逻辑。此时已获取到完整的 ActivityInfo,但还未生成 Record,不会污染栈结构。