前言
Activity 启动过程文章系列会按阶段拆开分析。上一篇已经把应用进程初始化完成;本文只聚焦 Activity 启动阶段:system_server 如何把等待中的 Activity 启动事务发给客户端,以及客户端如何依次走到 onCreate()、onStart()、onResume()。
启动流程梳理:
- Activity 启动流程(一)—— Launcher 阶段
- Activity 启动流程(二)—— AMS 处理阶段
- Activity 启动流程(三)—— 应用程序进程启动阶段
- Activity 启动流程(四)—— ActivityThread 初始化阶段
- Activity 启动流程(五)—— Activity 启动阶段
代码基于 android-14.0.0_r9。
本文关注的是 “目标 Activity 实例如何在客户端被真正创建并进入前台”。进程创建、Application 初始化这些事情,已经在前两篇完成了。
1. 一句话总览
这一阶段的核心是:应用进程完成 attachApplication 之后,system_server 重新找到这个进程里等待启动的 ActivityRecord,通过 realStartActivityLocked() 构造 LaunchActivityItem 和 ResumeActivityItem,再用 ClientTransaction 发给客户端;客户端收到事务后,依次执行 handleLaunchActivity()、performLaunchActivity()、handleStartActivity()、handleResumeActivity(),最终把 Activity 推到可见且 resumed 的状态。
主链路如下:
finishAttachApplicationInner()→mAtmInternal.attachApplication()→RootWindowContainer.attachApplication()→AttachApplicationHelper.process()→ActivityTaskSupervisor.realStartActivityLocked()→LaunchActivityItem+ResumeActivityItem→ClientTransaction.schedule()→ActivityThread.scheduleTransaction()→TransactionExecutor.executeTransactionItems()→LaunchActivityItem.execute()→handleLaunchActivity()→performLaunchActivity()→handleStartActivity()→handleResumeActivity()
flowchart LR
A[AMS.finishAttachApplicationInner]
B[ATMS.attachApplication]
C[realStartActivityLocked]
D[LaunchActivityItem + ResumeActivityItem]
E[ClientTransaction]
F[ActivityThread.scheduleTransaction]
G[handleLaunchActivity]
H[performLaunchActivity / onCreate]
I[handleStartActivity / onStart]
J[handleResumeActivity / onResume]
A --> B --> C --> D --> E --> F --> G --> H --> I --> J
这条链路的终点不是“请求已经发出”,而是 客户端 Activity 已经完成首次创建并进入 resumed/visible 状态。
2. Activity 启动阶段源码分析
2.1 重新接回等待中的 Activity:attachApplication 完成后 ATMS 开始真实启动
应用进程完成 bindApplication 之后,AMS 会继续执行 finishAttachApplicationInner():
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
...
synchronized (this) {
...
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
}
}
这一步的意义非常直接:现在进程已经可用,system_server 可以回过头来继续处理之前因为“进程还没起来”而挂起的 Activity 启动请求。
ATMS 接手之后,会继续走到 RootWindowContainer.attachApplication(),再由内部 helper 找出哪些 ActivityRecord 正在等这个进程:
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
try {
return mAttachApplicationHelper.process(app);
} finally {
mAttachApplicationHelper.reset();
}
}
它内部最终会命中 realStartActivityLocked():
// RootWindowContainer.AttachApplicationHelper
public boolean test(ActivityRecord r) {
if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard
|| r.app != null || mApp.mUid != r.info.applicationInfo.uid
|| !mApp.mName.equals(r.processName)) {
return false;
}
if (mTaskSupervisor.realStartActivityLocked(r, mApp,
mTop == r && r.getTask().canBeResumed(r),
true /* checkConfig */)) {
mHasActivityStarted = true;
}
return false;
}
也就是说,这一阶段的真正起点不是 Launcher,也不是 startActivityAsUser(),而是:system_server 确认目标进程已经 attach 完成,然后把等待中的 ActivityRecord 真正发往客户端。
2.2 构造启动事务:realStartActivityLocked() 把 launch 和 resume 打包
realStartActivityLocked() 是 system_server 侧把 Activity 启动事务发给客户端的关键方法:
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
final LaunchActivityItem launchActivityItem = LaunchActivityItem.obtain(r.token,
r.intent, System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), deviceId,
r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
results, newIntents, r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken);
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(r.token, isTransitionForward,
r.shouldSendCompatFakeFocus());
} else {
lifecycleItem = PauseActivityItem.obtain(r.token);
}
mService.getLifecycleManager().scheduleTransactionAndLifecycleItems(
proc.getThread(), launchActivityItem, lifecycleItem);
...
}
这里有一个很重要的设计点:Activity 的首次启动不是一个单独动作,而是一组事务项。
LaunchActivityItem负责把 Activity 创建出来;ResumeActivityItem决定它最后要进入什么生命周期状态。
也就是说,system_server 在这一层做的是 “生命周期事务编排”,而不是直接执行客户端代码。
2.3 事务入客户端:ClientTransaction 把 system_server 的决策送到主线程
这些事务最终会通过 ClientTransaction 发给客户端:
// frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client,
@NonNull ClientTransactionItem transactionItem,
@NonNull ActivityLifecycleItem lifecycleItem) throws RemoteException {
...
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
clientTransaction.addCallback(transactionItem);
clientTransaction.setLifecycleStateRequest(lifecycleItem);
scheduleTransaction(clientTransaction);
}
// frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
客户端的 ActivityThread 收到它以后,不会在 Binder 线程里直接执行,而是转到主线程消息循环:
// frameworks/base/core/java/android/app/ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
// frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void executeTransactionItems(@NonNull ClientTransaction transaction) {
final List<ClientTransactionItem> items = transaction.getTransactionItems();
for (int i = 0; i < items.size(); i++) {
final ClientTransactionItem item = items.get(i);
if (item.isActivityLifecycleItem()) {
executeLifecycleItem(transaction, (ActivityLifecycleItem) item);
} else {
executeNonLifecycleItem(transaction, item,
shouldExcludeLastLifecycleState(items, i));
}
}
}
这个顺序很关键:先执行非生命周期项(launch),再执行生命周期项(resume/pause)。这样客户端才能先有 Activity 实例,再去推进状态机。
2.4 客户端真正创建 Activity:performLaunchActivity() 走到 onCreate()
非生命周期项里最关键的是 LaunchActivityItem.execute():
// frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
public void execute(@NonNull ClientTransactionHandler client,
@NonNull PendingTransactionActions pendingActions) {
ActivityClientRecord r = new ActivityClientRecord(mActivityToken, mIntent, mIdent, mInfo,
mOverrideConfig, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
mTaskFragmentToken);
client.handleLaunchActivity(r, pendingActions, mDeviceId, null /* customIntent */);
}
然后进入 ActivityThread.handleLaunchActivity():
// frameworks/base/core/java/android/app/ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
真正创建实例和调用 onCreate() 的地方在 performLaunchActivity():
// frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken, r.shareableActivityToken);
...
mInstrumentation.callActivityOnCreate(activity, r.state);
...
r.activity = activity;
r.setState(ON_CREATE);
...
return activity;
}
这一段才真正把服务端的 ActivityRecord 变成客户端里的 Activity 实例。到 callActivityOnCreate(...) 为止,首次 onCreate() 就已经发生了。
2.5 生命周期收尾:handleStartActivity()、handleResumeActivity() 把 Activity 推到前台
Activity 创建完之后,事务执行器继续处理生命周期项。
先是 handleStartActivity():
// frameworks/base/core/java/android/app/ActivityThread.java
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
final Activity activity = r.activity;
...
activity.performStart("handleStartActivity");
r.setState(ON_START);
...
updateVisibility(r, true /* show */);
}
这一步把 Activity 从 ON_CREATE 推到 ON_START。
再往后是 handleResumeActivity():
// frameworks/base/core/java/android/app/ActivityThread.java
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
...
if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
...
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
}
}
...
}
这里有两件事同时发生:
performResumeActivity(...)推进 Activity 到 resume 路径;- Window / DecorView 被真正加入窗口系统,Activity 开始进入“对用户可见”的状态。
所以本文的收口点不是单纯的 onResume() 回调,而是:客户端 Activity 完成创建、启动、恢复,窗口也进入可见路径。
3. 关键设计点
3.1 system_server 负责编排,客户端负责执行
realStartActivityLocked() 决定要发哪些事务项,但它不直接调用客户端生命周期;真正执行 onCreate()、onStart()、onResume() 的,是 ActivityThread。
3.2 LaunchActivityItem 和 ResumeActivityItem 是分层设计
首次启动并没有把所有动作揉成一个大方法,而是拆成“创建实例”和“推进状态”两个事务项。这样生命周期顺序更清楚,也更利于事务系统复用。
3.3 ActivityThread 是客户端执行器,不是决策者
客户端只是按事务执行:创建 ActivityClientRecord、实例化 Activity、调用生命周期、把窗口加到 WindowManager。至于该启动哪个 Activity、以什么状态启动,决策都已经在 system_server 完成了。
4. 总结
Activity 启动阶段的本质,是 system_server 把等待中的 ActivityRecord 编排成客户端事务,客户端再按顺序执行创建、启动、恢复和显示流程。
到 handleLaunchActivity()、performLaunchActivity()、handleStartActivity()、handleResumeActivity() 这一整条链跑完,目标 Activity 才算真正以一个前台可见组件的形式完成首次启动。