Activity啟動原始碼解析(Android12)
theme: channing-cyan
四大元件系列
一概述
Activity 的啟動非常複雜,其中涉及到多個程序參與工作。Activity 所在的程序,系統程序(Zygote),AMS 程序,還有點選桌面圖示所在的 Launch 程序。由於這個原因,所以很難在一篇文章中,將它們所有的工作內容梳理清楚。並且由於其中大部分邏輯,都是在 AMS 中完成的,所以我打算本篇僅描述 Activity 的啟動流程,關於程序的啟動,Activity 的棧管理,都放在 AMS 的篇章中。
本篇先梳理整個啟動流程。關於啟動流程,本篇只梳理出大致脈絡即可,關於其中的程序啟動,程序管理,任務棧管理,後續會單獨列舉出來介紹。
二 startActivity
首先是我們熟悉的 startActivity,需要注意的是,startActivity 需要區分 Activity 中的 startActivity 和 Context 中的 startActivity,這一點在後面有不同的邏輯。
2.1 Context 的 startActivity
startActivity 前面這些流程大家應該都比較熟悉,所以我就簡單跳過了。Context 中的 startActivity 會呼叫到 ContextImpl.startActivity。
```java [frameworks/base/core/java/android/app/ContextImpl.java]
public void startActivity(Intent intent, Bundle options) { warnIfCallingFromSystemProcess();
// 一些異常判斷
...
// 呼叫 Instrumentation 的 execStartActivity
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
} ```
2.2 Activity 的 startActivity
```java public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); // 呼叫 Instrumentation 的 execStartActivity Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
} ```
對比兩個兩個 startActivity,我們發現 Activity 中的 startActivity 多了幾個引數,分別是 mToken 和 this。這兩個值決定了之後 Activity 啟動中的棧管理邏輯,它們一個是後續的 token,一個則是 resultTo。
Activity 的棧管理是 Activity 啟動的重要內容,後面在 AMS 中會詳細講述。
mMainThread 的類似是 ActivityThread,這裡其實就是獲取 ActivityThread 中的 Instrumentation,呼叫 Instrumentation.execStartActivity。
三 Instrumentation.execStartActivity
```java public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// 啟動 Activity
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
notifyStartActivityResult(result, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
} ```
在 execStartActivity 中,會通過 ActivityTaskManager(後面檢查 ATM) 的 getService 來啟動 Activity。這裡 getService 拿到的就是 ActivityTaskManagerService(後面簡稱為 ATMS)。
注意,我們需要關注mToken 和 this這兩個引數的變化,這裡它們變成了token和target,最後token會變成resultTo
3.1 ActivityTaskManager.getService
獲取 ATMS 服務的 IBinder 物件,這個服務在之前 AMS 服務啟動的時候會發布。到這裡,就會通過 IBinder 呼叫到對應的 AMS 程序,後續的邏輯就是在 AMS 程序中運行了。
```java [frameworks/base/core/java/android/app/ActivityTaskManager.java]
public static IActivityTaskManager getService() { return IActivityTaskManagerSingleton.get(); }
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton
3.2 ActivityTaskManagerService.onStart
java
public void onStart() {
publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
mService.start();
}
Context.ACTIVITY_TASK_SERVICE 服務其實就是 ATMS,在 ATMS 的 onStart 中,會將自己釋出到 ServiceManager。所以啟動 Activitiy 最終會呼叫到 ATMS 的 startActivity。
然後在 ATMS 的 startActivity 內部,會呼叫到 startActivityAsUser,所以我們直接看 startActivityAsUser。
3.3 ActivityTaskManagerService.startActivityAsUser
```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) { assertPackageMatchesCallingUid(callingPackage); enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// 獲取 一個 ActivityStartController,然後通過它獲取一個 ActivityStarter
// 然後執行 execute
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
} ```
startActivityAsUser 這個函式更簡單,就是獲取一個 ActivityStarter,然後設定一堆的引數之後,呼叫 execute。這裡的引數很多,但是我們只需要關注其中重要的幾個即可
- intent:啟動 Activity 傳入的引數
- caller:這次呼叫的 ApplicationThread。(傳入的是 IApplicationThread,ApplicationThread 是 ActivityThread 的內部類,它繼承自 IApplicationThread,IApplicationThread 又繼承自 IInterface,ApplicationThread 是用於應用程序和系統程序通訊使用的)
- resultTo:這次啟動的動作來自哪個 Activity(可以是同一個程序,也可以是不同的程序,例如桌面的 Launch 程序。或者可以為空,例如從 Service 或其他非 Activity 的 Context 中啟動),傳入的是當前 Activity 的 Token(Token 是每個 Activity 的唯一標識)。
四 ActivityStarter
ActivityStarter 看名字也就知道,它這個類的任務就是用來啟動 Activity 的。
4.1 ActivityStarter.obtainStarter
首先會通過一個工廠來獲得 ActivityStarter,工廠中有一個 ActivityStarter 池,ActivityStarter 是可以複用的。
java
[frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java]
ActivityStarter obtainStarter(Intent intent, String reason) {
// Factory 其實就是 ActivityStarter 的一個內部類。
// 這裡獲取 ActivityStarter 其實就是從 Factory 中的一個 ActivityStarter 池獲取
return mFactory.obtain().setIntent(intent).setReason(reason);
}
obtainStarter 其實就是從 ActivityStarter.Factory 的池子中,取出一個 ActivityStarter。因為 ActivityStarter 是可以複用的,所以有些引數並不需要每次都設定,它會使用之前的引數。
4.2 ActivityStarter.execute
```java [frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java]
int execute() { try { ...
int res;
synchronized (mService.mGlobalLock) {
// 前面做了很多關於 Intent 引數的判斷和引數解析相關的操作
...
// 執行啟動流程
res = executeRequest(mRequest);
...
}
} finally {
onExecutionComplete();
}
} ```
4.3 ActivityStarter.executeRequest
executeRequest 開始就準備啟動 Activity 了。這個函式很長,有 400 多行,根據 Google 官方的註釋解釋。這個函式主要做了這麼兩件事
- 首先執行初步的檢查
- 呼叫 startActivityUnchecked 到 startActivityInner
```java
private int executeRequest(Request request) {
...
// 前面會通過 Supervisor.resolveActivity 做一些 Activity 和 Intent 的解析,
// 判斷是否有匹配要啟動的 Activity
// 如果存在多個,則會呼叫到 ActivityTaskSupervisor.resolveIntent 中
// 最後通過 PMS 讓使用者選擇
// 前面做了好多檢查,最後會把這些引數封裝到一個 ActivityRecord 中
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
mLastStartActivityRecord = r;
...
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
...
return mLastStartActivityResult;
} ```
在 executeRequest 中,會將請求的引數封裝到一個 ActivityRecord 中,然後呼叫 startActivityUnchecked。
4.4 ActivityStarter.startActivityUnchecked
startActivityUnchecked 主要就是呼叫了 startActivityInner,它才是真正執行啟動 Activity 的邏輯。
```java private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants) {
...
try {
...
// 真正執行啟動 Activity 的邏輯
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
...
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
} ```
4.5 ActivityStarter.startActivityInner
從這一步開始,就是正式的啟動 Activity 了,當然,啟動 Activity 的過程中有三個重點
- 不同啟動模式的 Activity 的啟動原理
- 冷啟動和熱啟動的原理
- Activity 是如何顯示到介面上的
```java [frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java]
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants) {
// 設定初始狀態
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
// 首先就是計算 Activity 的啟動模式
// 獲得一個的 Flag,這玩意就是我們設定給 Intent 的。
computeLaunchingTaskFlags();
// 處理源 Activity 的任務棧
// 如果源 Activity 正在 finish 則需要開啟一個新的棧
computeSourceRootTask();
// mLaunchFlags 就是前面計算的,這裡設定給 mIntent
// 其實和我們啟動 Activity 時自定義 Flag 很像
mIntent.setFlags(mLaunchFlags);
// Reusable 複用,這裡是獲取可以複用的 Task
final Task reusedTask = getReusableTask();
//是否需要凍結 Task 列表
if (mOptions != null && mOptions.freezeRecentTasksReordering()
&& mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
&& !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
mFrozeTaskList = true;
mSupervisor.mRecentTasks.setFreezeTaskListReordering();
}
// 是否存在一個可以現在使用的 Task
// 是否有複用,如果沒有,是否可以計算獲取一個
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
// 如果沒有可以現在使用的 Task,那麼就建立一個新 Task
final boolean newTask = targetTask == null;
mTargetTask = targetTask;
// 計算啟動引數
computeLaunchParams(r, sourceRecord, targetTask);
// 判斷是否可以通過 targetTask 或者新建 Task 啟動的 Activity
int startResult = isAllowedToStart(r, newTask, targetTask);
if (startResult != START_SUCCESS) {
return startResult;
}
// 獲取棧頂沒有 finish 的 activity
final ActivityRecord targetTaskTop = newTask
? null : targetTask.getTopNonFinishingActivity();
if (targetTaskTop != null) {
// 看一下棧頂的 Task targetTaskTop 是否可以回收複用
startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
} else {
mAddingToTask = true;
}
// 如果要啟動的 Activity 與當前在頂部的 Activity 相同,那麼我們需要檢查它是否應該只被啟動一次。
final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
if (topRootTask != null) {
startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
}
if (mTargetRootTask == null) {
// 獲得一個棧 Task
mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
if (newTask) {
// 如果是新建 Task
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// 關聯 Task 與 ActivityRecord
// 這個函式也會呼叫 addOrReparentStartingActivity
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
// 將要啟動的 Activity 新增到 targetTask
// 並且會將此 Activity 新增到最近啟動的 ActivityRecord 中,後續可以通過 findActivity 複用
addOrReparentStartingActivity(targetTask, "adding to task");
}
if (!mAvoidMoveToFront && mDoResume) {
mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
if (mOptions != null) {
if (mOptions.getTaskAlwaysOnTop()) {
mTargetRootTask.setAlwaysOnTop(true);
}
}
if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.mInternal.isDreaming()) {
// Launching underneath dream activity (fullscreen, always-on-top). Run the launch-
// -behind transition so the Activity gets created and starts in visible state.
mLaunchTaskBehind = true;
r.mLaunchTaskBehind = true;
}
}
mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
mStartActivity.getUriPermissionsLocked());
if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
// we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
final PackageManagerInternal pmInternal =
mService.getPackageManagerInternalLocked();
final int resultToUid = pmInternal.getPackageUid(
mStartActivity.resultTo.info.packageName, 0 /* flags */,
mStartActivity.mUserId);
pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
resultToUid /*visible*/, true /*direct*/);
}
if (newTask) {
EventLogTags.writeWmCreateTask(mStartActivity.mUserId,
mStartActivity.getTask().mTaskId);
}
mStartActivity.logStartActivity(
EventLogTags.WM_CREATE_ACTIVITY, mStartActivity.getTask());
mTargetRootTask.mLastPausedActivity = null;
mRootWindowContainer.startPowerModeLaunchIfNeeded(
false /* forceSend */, mStartActivity);
mTargetRootTask.startActivityLocked(mStartActivity,
topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask,
mKeepCurTransition, mOptions, sourceRecord);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
// 要啟動的 Activity 無法獲取焦點
if (!mTargetRootTask.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
// 如果 Activity 不可見就無法恢復
// 如有要確保可見,就會觸發進入動畫
// 並且,被覆蓋的 Activity,直到覆蓋物被移除前,都是不可見的
mTargetRootTask.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
// 告訴 WMS 繼續執行,因為現在 Activity 還無法恢復。
mTargetRootTask.mDisplayContent.executeAppTransition();
} else {
//
if (mTargetRootTask.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
mTargetRootTask.moveToFront("startActivityInner");
}
// 恢復棧頂的 Activity
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
// Activity 啟動時立即更新最近的任務列表
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
return START_SUCCESS;
} ```
startActivityInner 這個函式做了很多事,但是這裡就不展開了,後面在 Activity 的棧管理中還會詳細說明這個函式。我們現在知道,它通過 RootWindowContainer 呼叫了 resumeFocusedTasksTopActivities。
五 RootWindowContainer
5.1 resumeFocusedTasksTopActivities
```java [frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java]
boolean resumeFocusedTasksTopActivities( Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions, boolean deferPause) {
// mTaskSupervisor 判斷是否恢復狀態
if (!mTaskSupervisor.readyToResume()) {
return false;
}
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
// 恢復棧頂的 Activity
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
...
if (!resumedOnDisplay[0]) {
...
if (focusedRoot != null) {
final Task focusedRoot = display.getFocusedRootTask();
// 恢復棧頂的 Activity
result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetRootTask == null) {
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
} ```
然後在 resumeTopActivityUncheckedLocked 中,呼叫到了 Task.resumeTopActivityInnerLocked。
六 Task
Task 是系統對 ActivityRecord 的又一層封裝。
Task.resumeTopActivityInnerLocked
```java
@GuardedBy("mService") private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) { ...
if (next.attachedToProcess()) {
...
try {
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken);
...
// 啟動事務
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
} catch (Exception e) {
// Whoops, need to restart this activity!
...
// 呼叫
mTaskSupervisor.startSpecificActivity(next, true, false);
return true;
}
...
} else {
// Whoops, need to restart this activity!
...
mTaskSupervisor.startSpecificActivity(next, true, true);
}
return true;
} ```
七 ActivityTaskSupervisor
ActivityTaskSupervisor 是 Activity 棧的超級管理者,所以它負責者 Activity 的棧的。
7.1 startSpecificActivity
```java void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) { ... if (wpc != null && wpc.hasThread()) { try {
// 真正啟動 Activity
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
...
}
...
} ```
7.2 realStartActivityLocked
```java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException {
...
// 這裡的 proc.getThread() 其實拿到的是 ActivityThread
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
try {
...
// 啟動事務,mService 是 ActivityTaskManagerService
// 拿到的 Manager 是 ClientLifecycleManager
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
} catch (RemoteException e) {
...
return true;
} ```
realStartActivityLocked 裡首先會通過 proc.getThread 拿到一個 ActivityThread,然後通過 ActivityThread 拿到一個 ClientTransaction。
然後會有一個 mService,它就是 ATMS,然後通過 ATMS 的 getLifecycleManager 拿到 ClientLifecycleManager 並呼叫它的 scheduleTransaction。
八 ClientLifecycleManager
8.1 scheduleTransaction
```java void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient();
// 執行 ClientTransaction 的 schedule
transaction.schedule();
if (!(client instanceof Binder)) {
// 如果客戶端不是 Binder 的例項--即這是一個遠端呼叫,
// 此時回收該物件是安全的。
// 所有用於本地呼叫的物件在 ActivityThread 中的客戶端上執行完事務後將被回收
transaction.recycle();
}
} ```
九 ClientTransaction
9.1 schedule
```java [frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java]
// 這個 mClient,其實就是之前建立的 private IApplicationThread mClient;
public void schedule() throws RemoteException { mClient.scheduleTransaction(this); } ```
這裡有一個 mClient,其實就是之前 obtain 中傳入的 proc.getThread。而這個 proc 其實就是 WindowProcessController。而獲取到的 Thread 就是 IApplicationThread。
這裡用到了跨程序通訊,這個 IApplicationThread 真正的實現是 ActivityThread 的內部類 ApplicationThread。
所以前面呼叫的 transaction.schedule 其實就是 ApplicationThread.scheduleTransaction。而 ApplicationThread 其實是 ActivityThread 的內部類。
十 ActivityThread
10.1 scheduleTransaction
java
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
呼叫到了 ActivityThread 的 scheduleTransaction,然後 ActivityThread 裡並沒有 scheduleTransaction,仔細一看,原來它繼承自 ClientTransactionHandler,真正的實現在它的父類。
java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
十一 ClientTransactionHandler
11.1 scheduleTransaction
```java [frameworks/base/core/java/android/app/ClientTransactionHandler.java]
void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } ```
然後在父類 ClientTransactionHandler 中,會通過訊息機制傳送一條 EXECUTE_TRANSACTION 的訊息,這個會呼叫到 ActivityThread 的 Handle 中。
在 ActivityThread 的訊息處理中,首先會執行這個 ClientTransaction,然後再將它回收(呼叫 recycle)。
java
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
接下來的流程就比較簡單了,通過訊息機制,在 ActivityThread 的 handleMessage 中,呼叫了 execute 執行之前傳遞過來的 ClientTransaction。
十二 TransactionExecutor
12.1 execute
```java [frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java]
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
} ```
12.2 executeCallbacks
```java @VisibleForTesting public void executeCallbacks(ClientTransaction transaction) { ... for (int i = 0; i < size; ++i) { ...
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
} ```
12.3 cycleToPath
java
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
...
performLifecycleSequence(r, path, transaction);
}
12.4 performLifecycleSequence
TransactionExecutor 中有一個 mTransactionHandler,它的型別是 ClientTransactionHandler,這個變數其實就是在建立的時候初始化的,在 ActivityThread 中,ActivityThread 將自己作為引數傳遞了進來,所以這個 mTransactionHandler 其實就是 ActivityThread。
```java private void performLifecycleSequence(ActivityClientRecord r, IntArray path, ClientTransaction transaction) { final int size = path.size(); for (int i = 0, state; i < size; i++) { state = path.get(i);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions,
null /* activityOptions */);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r, false /* finished */,
false /* userLeaving */, 0 /* configChanges */,
false /* autoEnteringPip */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
} ```
最後就通過這裡的 ActivityThread 呼叫到了對應的生命週期。
十三 總結
到這裡,Activity 的啟動流程我們算是梳理完了,但是,Activity 啟動的複雜程度遠不止如此,本篇部落格中,我忽略了其中的很多細節。例如:
- 程序的啟動(啟動 Activity 時會判斷程序的存在與否,應用的程序是如何啟動的)
- 程序的管理(通過程序的啟動,引申出程序是如何管理的,Activity 的前後臺切換,優先順序與系統殺程序)
- Activity 棧的管理(Activity 棧是如何複用的)
由於以上的邏輯涉及很多 AMS 的工作原理,所以我打算放 AMS 原始碼解析中說明。下面我們用一幅圖來總結一下 Activity 的啟動的大致流程。
- Activity啟動原始碼解析(Android12)
- 從MediaServer看Binder的使用方式(一)
- 從MediaServer看Binder的使用方式(二)
- [Android禪修之路] 解讀Layer
- [Android禪修之路] Android圖形系統,從Activity到Surface
- [Android禪修之路] 解讀 GraphicBuffer 之 Framework 層
- [Android禪修之路] 解讀SurfaceFlinger中的BufferQueue
- [Android禪修之路] SurfaceFlinger 合成中的工作
- [Android禪修之路] SurfaceFlinger 中的一些物件
- [Android禪修之路] SurfaceFlinger 合成前的預處理
- [Android禪修之路] SurfaceFlinger合成總覽
- [Android禪修之路] SurfaceFlinger的啟動過程
- [Android禪修之路] Android 圖形系統開篇