前言
启动流程梳理:
- Activity 启动流程(一)—— Launcher 阶段
- Activity 启动流程(二)—— AMS 处理阶段
- Activity 启动流程(三)—— 应用程序进程启动阶段
- Activity 启动流程(四)—— ActivityThread 初始化阶段
- Activity 启动流程(五)—— Activity 启动阶段
代码基于 android-14.0.0_r9。
从 Android 10 开始,Activity 启动主链已经拆分到 ATMS / WM 侧:ActivityTaskManagerService 负责入口与裁决,ActivityStarter 负责启动决策,RootWindowContainer / Task 负责把目标 Activity 推到可恢复路径上。
1. 一句话总览
这一阶段的核心不是“把进程真正拉起来”或“让客户端立刻执行 onCreate()”,而是:系统侧先接住启动请求,做安全与用户校验,组装 ActivityStarter,创建或复用 Task,挂载 ActivityRecord,然后尝试恢复目标顶部 Activity;如果发现目标进程还没起来,再把请求异步交给进程启动链路。
主链路如下:
ActivityTaskManagerService.startActivityAsUser()→ActivityStartController.obtainStarter()→ActivityStarter.execute()→executeRequest()→startActivityUnchecked()→startActivityInner()→RootWindowContainer.resumeFocusedTasksTopActivities()→Task.resumeTopActivityUncheckedLocked()→TaskFragment.resumeTopActivity()→ActivityTaskSupervisor.startSpecificActivity()/mAtmService.startProcessAsync()
flowchart LR
A[ATMS.startActivityAsUser]
B[ActivityStartController.obtainStarter]
C[ActivityStarter.execute / executeRequest]
D[创建 ActivityRecord]
E[复用或创建 Task]
F[resumeFocusedTasksTopActivities]
G{目标进程是否已存在}
H[发送 Resume 事务给现有进程]
I[startSpecificActivity]
J[startProcessAsync 异步交接]
A --> B --> C --> D --> E --> F --> G
G -- 已存在 --> H
G -- 不存在 --> I --> J
这条链路里,ATMS/WM 做的是“系统侧裁决与挂载”;真正的进程创建,从 startProcessAsync() 之后才进入下一篇。
2. AMS 处理阶段源码分析
2.1 入口收口:ATMS 先做调用方校验,再把请求交给 ActivityStarter
Launcher 侧 Binder 调用最终会进入 ActivityTaskManagerService.startActivityAsUser():
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(opts)
.setUserId(userId)
.execute();
}
这一层的职责很明确:
- 做入口安全收口:校验调用包名、隔离进程、目标用户是否合法。
- 把原始启动参数整理成内部请求:例如
SafeActivityOptions、userId、resultTo。 - 把真正的启动裁决委托给
ActivityStarter。
ActivityStarter 是启动 Activity 的控制类,根据设置的参数来决定如何根据 Intent 和 Flags 来启动 Activity,并将 Activity 和 Task 以及 Stack 相关联。它在调用 ActivityStarter 的 execute 方法之前一直有效。
ATMS 在 startActivityAsUser() 中完成调用方与用户合法性校验并封装启动参数,将请求统一收口后委托给 ActivityStarter 做真正的启动决策与执行。
2.2 执行器装配:ActivityStartController 获取 starter,ActivityStarter 创建 ActivityRecord
ActivityStartController 只负责拿到一个可配置的 ActivityStarter:
// frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
真正的核心从 ActivityStarter.execute() 进入 executeRequest():
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
...
res = executeRequest(mRequest);
...
}
private int executeRequest(Request request) {
...
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setResultTo(resultRecord)
.setRequestCode(requestCode)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, checkedOptions,
inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid);
return mLastStartActivityResult;
}
这里最关键的变化是:一次抽象的启动请求,先被系统侧具象化成一个 ActivityRecord。
ActivityRecord 还不是客户端里的 Activity 实例,它只是 system_server 里对这次启动的服务端描述:调用来源、目标组件、返回链路、启动参数、所属任务关系,后续都围绕它来决策。
executeRequest() 的核心职责是:把一次 Activity 启动请求从“外部请求”加工成“系统可执行的 ActivityRecord”,期间完成调用方识别、结果回调处理、Intent 解析校验、语音兼容检查、权限检查、后台启动限制、拦截器改写、权限审查、Instant App 改写,最后交给 startActivityUnchecked() 处理 Task 和真正启动。
下一步才是决定它该挂到哪个 Task、要不要复用已有栈、要不要把任务切到前台。
2.3 任务决策:startActivityInner 决定复用还是新建,并把 ActivityRecord 挂进 Task
startActivityUnchecked() 主要负责把流程推进到 startActivityInner();真正的任务决策发生在这里:
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, ...) {
...
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, options, inTask, inTaskFragment, balVerdict,
intentGrants, realCallingUid);
...
}
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, ...) {
setInitialState(r, options, inTask, inTaskFragment, startFlags, sourceRecord,
voiceSession, voiceInteractor, balVerdict.getCode(), realCallingUid);
computeLaunchingTaskFlags();
mIntent.setFlags(mLaunchFlags);
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
final boolean newTask = targetTask == null;
if (mTargetRootTask == null) {
mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
if (newTask) {
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
addOrReparentStartingActivity(targetTask, "adding to task");
}
if (!mAvoidMoveToFront && mDoResume) {
mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
}
if (mDoResume) {
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
...
}
这一段做的不是“真正执行生命周期”,而是先完成 Task 维度的落位:
- 根据
launchMode、flags、来源 Activity、历史任务等因素,判断这次启动是复用旧 Task还是新建 Task。 - 如果需要新任务,就通过
setNewTask()把ActivityRecord正式挂进去。 - 如果是复用路径,就把这次启动和已有任务关系理顺。
- 最后在任务层级准备好之后,再调用
resumeFocusedTasksTopActivities()进入“把谁推到前台”的阶段。
这也是系统侧很重要的一层分工:先把 Activity 放进正确的任务结构里,再决定可见性和恢复。
2.4 恢复顶部 Activity:如果目标进程不存在,就在这里交接到进程启动链路
任务落位之后,RootWindowContainer 会推动顶部 Activity 的恢复:
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
if (!mTaskSupervisor.readyToResume()) {
return false;
}
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
...
}
Task.resumeTopActivityUncheckedLocked() 和 resumeTopActivityInnerLocked() 主要是中间分发层,真正决定“往客户端 resume,还是先去拉进程”的关键分支,在 TaskFragment.resumeTopActivity():
// frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean skipPause) {
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
...
boolean pausing = !skipPause && taskDisplayArea.pauseBackTasks(next);
if (mResumedActivity != null) {
pausing |= startPausing(mTaskSupervisor.mUserLeaving, false, next,
"resumeTopActivity");
}
if (pausing) {
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false, true, false, false);
} else if (!next.isProcessRunning()) {
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
}
return true;
}
...
if (next.attachedToProcess()) {
...
final ResumeActivityItem resumeActivityItem = ResumeActivityItem.obtain(...);
mAtmService.getLifecycleManager().scheduleTransaction(...);
} else {
mTaskSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
这里可以把恢复路径简化成两个分支:
- 进程已存在:系统继续准备可见性和状态切换,然后通过
ResumeActivityItem把恢复事务发给目标进程。 - 进程不存在:系统不会在这里直接创建进程,而是转到
startSpecificActivity()/startProcessAsync()做异步交接。
startSpecificActivity() 负责检查目标进程是否已经具备可用的 IApplicationThread:
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
if (wpc != null && wpc.hasThread()) {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
}
final boolean isTop = andResume && r.isTopRunningActivity();
mService.startProcessAsync(r, knownToBeDead, isTop,
isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_ACTIVITY);
}
而 startProcessAsync() 只是一个异步交接点:
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
}
这段代码有两个信息非常关键:
- ATMS 这里没有直接 fork 进程。
- 它通过消息把请求异步转交给
ActivityManagerInternal.startProcess(...),保留了清晰的异步交接边界。
后面 AMS 如何处理 startProcess、如何走到 ProcessList / Zygote,那已经是下一篇的主题了。
3. 关键设计点
3.1 统一入口,具体决策后置到 ActivityStarter
ActivityTaskManagerService.startActivityAsUser() 不直接处理复杂的任务复用和生命周期切换,而是先做安全与参数收口,再委托给 ActivityStarter。这种分层把“入口校验”和“启动裁决”拆开了,入口更稳定,执行器更聚焦。
3.2 先建服务端模型,再做前台切换
executeRequest() 先创建 ActivityRecord,startActivityInner() 再决定它挂到哪个 Task。也就是说,系统不是先 resume 再补结构,而是先把任务层级摆正,再推进可见性和生命周期。
3.3 进程启动是异步交接,不在当前决策链里硬做
startProcessAsync() 通过 mH.sendMessage(...) 把请求转给 ActivityManagerInternal.startProcess(...)。本质上这是一次“系统侧裁决链”到“进程创建链”的边界切换。这样做的价值是两点:避免锁耦合,也让任务决策和进程创建各自归位。
4. 高频误区 / QA
4.1 这篇明明叫 AMS 处理阶段,为什么源码大多在 ATMS / WM?
因为 Android 10 之后,Activity 与任务管理能力已经从传统 AMS 里拆分到了 ActivityTaskManagerService 和 WindowManager 相关结构里。系列标题沿用了更通俗的叫法,但实际主链应以源码为准。
4.2 ActivityRecord 创建出来,是不是就等于 Activity 已经启动了?
不是。ActivityRecord 只是 system_server 里的服务端记录,表示“系统已经接受并描述了这次启动”。真正的客户端实例化、onCreate()、onResume() 还要看后续是走已有进程恢复,还是先进入进程启动链。
4.3 本阶段会直接把应用进程创建出来吗?
不会。本文里的终点是 startProcessAsync(),它只是把“需要拉起目标进程”这件事异步交给 AMS 本地服务。真正的进程创建、Zygote 通信、ActivityThread 初始化,都属于后续阶段。
5. 总结
AMS 处理阶段的本质,不是“把 Activity 直接跑起来”,而是在 system_server 内部把一次启动请求变成一套可执行的任务与生命周期决策:先校验调用方,再创建 ActivityRecord,再决定 Task 复用或新建,最后推进顶部 Activity 的恢复。
如果目标进程已经存在,后续会进入客户端事务恢复路径;如果目标进程不存在,流程就在 startProcessAsync() 这里切到下一阶段。也就是说,本文的边界就是:ATMS / WM 完成启动裁决,AMS 进程启动链开始接管。