基於 Android 13 的 Activity 啟動流程分析
對於 Android 客戶端開發者來說,Activity 是我們再熟悉不過的一個元件了。它是 Android 四大元件之一,是一個用於直接與使用者互動的展示型 UI 元件。在開發過程中,啟動並建立一個 Activity 流程非常簡單,而在系統底層實際上做了大量的工作,之所以使用這麼簡單,得益於系統底層對於 Activity 的良好封裝。本篇內容我們著重來分析一下 Framework 層 Activity 的啟動與建立的過程。
一、前言
在 《不得不說的 Android Binder 機制與 AIDL》這篇文章中我們瞭解了通過如何通過 Binder 與 AIDL 進行跨程序通訊,在另一篇文章 《反思 Android 訊息機制的設計與實現》深入探討了 Handler 訊息機制的實現原理。這兩篇文章,尤其是通過 Binder 與 AIDL 跨程序通訊這塊內容是理解本篇文章的基礎,如果現在還不瞭解的同學建議先去閱讀這兩篇文章。
在平時的開發中,啟動一個新的 Activity 只需要在當前 Activity 中呼叫startActivity
方法,並傳入一個Intent 即可,例如,從 MainActivity 啟動一個 TestActivity 程式碼如下:
Java
Intent intent = new Intent(this, TestActivity.class);
startActivity(intent);
兩行看似簡單的程式碼,實際上經歷了與 system_service 程序的數次互相呼叫,才成功啟動了一個 Activity。為方便理解,後文中我們把啟動 Activity 的程序稱為客戶端,把 system_server 程序稱為服務端。
二、客戶端的呼叫流程
startActivity 的操作是由客戶端發起的,因此當前的程式碼執行在客戶端程序中。追進startActivity
即可看到如下原始碼:
```java // frameworks/base/core/java/android/app/Activity.java
ActivityThread mMainThread;
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
getAutofillClientController().onStartActivity(intent, mIntent);
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
// ...
} else {
// ...
}
}
```
可以看到,startActivity
方法最終會呼叫 startActivityForResult
方法,這個方法的核心程式碼是通過 Instrumentation
呼叫了 execStartActivity
。而 execStartActivity
方法中的第二個引數為 mMainThread.getApplicationThread()
,這裡的 mMainThread 即為 ActivityThread,通過 ActivityThread 獲取到了 ApplicationThread,ApplicationThread 是一個 Binder 類,這個類最終會被傳到服務端,在服務端作為客戶端的代理來呼叫客戶端的程式碼,關於這個類後文還會分析。
繼續跟進 Instrumentation 的 execStartActivity 方法,程式碼如下:
```java // frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
// ...
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// 通過 ActivityTaskManager 獲取 Service 來啟動 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);
// 檢查 Activity 的啟動結果,例如是否在 AndroidManifest 檔案中註冊,沒有則丟擲異常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
``` 上述方法的核心程式碼是通過 ActivityTaskManager 獲取到了一個 Service,具體是一個什麼 Service 這裡並不能看出來,我們繼續跟進 ActivityTaskManager 的 getService 可以看到如下程式碼:
```java // frameworks/base/core/java/android/app/ActivityTaskManager.java
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
``
這裡可以看到 getService 獲取到的是一個 IActivityTaskManager,IActivityTaskManager 是什麼呢?通過搜尋原始碼,發現它其實是一個 AIDL 類,目錄為:
frameworks/base/core/java/android/app/IActivityTaskManager.aidl`,因此,IActivityTaskManager#startActivity 在這裡肯定是一個跨程序的操作,到這裡程式碼就進入了服務端程序,即 system_server 程序。
三、服務端的呼叫流程
經過上一小節的分析,程式碼已經執行到了 system_server 程序,那在 system_server 程序中呼叫的是哪個類呢?熟悉 AIDL 的同學應該清楚,在編譯完程式碼後 IActivityTaskManager
這個 AIDL 檔案會生成一個 IActivityTaskManager.Stub 類,這個類繼承自 Binder, 並且會有一個名為 startActivity
的抽象方法。因此接下來我們需要找到哪個類繼承了 IActivityTaskManager.Stub 即可,通過全域性搜尋我們發現 ActivityTaskManagerService 繼承了 IActivityTaskManager.Stub,其部分原始碼如下:
```java // frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // ...
private ActivityStartController mActivityStartController;
@Override public final int startActivity(IApplicationThread caller, String callingPackage, String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); }
@Override public int startActivityAsUser(IApplicationThread caller, String callingPackage, String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId, true /validateIncomingUser/); }
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) {
// ... 省略配置項獲取與校驗
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
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();
}
}
```
可以看到,在這個類中 startActivity
最終呼叫了 startActivityAsUser
方法,這個方法中的程式碼也比較簡單,就是通過 getActivityStartController().obtainStarter
來配置相關引數,並最終執行 execute
。
getActivityStartController()
獲取到的是一個 ActivityStartController 物件,如下:
Java
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
接著呼叫了 ActivityStartController 的 obtainStarter,程式碼如下:
java
/// ActivityStartController
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
obtainStarter 返回的是一個 ActivityStarter 物件,忽略相關引數的配置,我們直接看 ActivityStarter 的 execute 方法,原始碼如下:
```java // frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private final ActivityTaskSupervisor mSupervisor;
int execute() { try { onExecutionStarted();
// ...
int res;
synchronized (mService.mGlobalLock) {
// ...
res = executeRequest(mRequest);
// ...
}
return getExternalResult(res);
}
} finally {
onExecutionComplete();
}
}
``
execute方法又呼叫了
executeRequest` 方法,原始碼如下:
```java // frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {
// ... 省略引數初始化及許可權校驗
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();
// ...
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, restrictedBgActivity, intentGrants);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
}
return mLastStartActivityResult;
}
``` executeRequest 方法中的核心是例項化了 ActivityRecord,並呼叫 startActivityUnchecked,
```java // frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, boolean restrictedBgActivity, NeededUriGrants intentGrants) {
try {
mService.deferWindowLayout();
try {
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
} finally {
// ...
}
} finally {
mService.continueWindowLayout();
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}`java
``
startActivityUnchecked方法中又呼叫了
startActivityInner`,原始碼如下:
```java // frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private final RootWindowContainer mRootWindowContainer;
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, boolean restrictedBgActivity, NeededUriGrants intentGrants) { setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor, restrictedBgActivity);
// 處理 Intent 中攜帶的 flags
computeLaunchingTaskFlags();
// 獲取啟動 Activity 的任務棧,這裡即獲取 MainActivity 所在的任務棧
computeSourceRootTask();
// ...
// 查詢可用的任務棧
final Task reusedTask = getReusableTask();
// ...
// 如果 reusedTask 不空,則使用 reusedTask 任務棧,否則尋找目標任務棧
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
// 目標任務棧為空,則標記為使用新任務棧,需要新建任務棧
final boolean newTask = targetTask == null;
mTargetTask = targetTask;
computeLaunchParams(r, sourceRecord, targetTask);
if (newTask) {
// 建立一個新的任務棧
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// 將 Activity 放入新建的任務棧
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
// 加入已有的任務棧
addOrReparentStartingActivity(targetTask, "adding to task");
}
// ...
if (mDoResume) {
// ...
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
return START_SUCCESS;
}
``
startActivityInner 方法中的程式碼比較複雜。經過了簡化處理,可以看到這個方法裡主要是處理任務棧相關的邏輯,如果找到可用的任務棧則直接使用這個任務棧,如果沒有找到,則新建一個任務棧。 在完成任務棧的處理之後通過
mRootWindowContainer.resumeFocusedTasksTopActivities`繼續 Activity 的啟動流程,這裡的 mRootWindowContainer 是 RootWindowContainer 的例項,resumeFocusedTasksTopActivities 程式碼如下:
```java // frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedTasksTopActivities( Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions, boolean deferPause) { // ...
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,deferPause);
}
// ...
return result;
}
``
這個方法中將啟動相關的程式碼交給了 Task 的
resumeTopActivityUncheckedLocked` 方法。程式碼如下:
```java frameworks/base/services/core/java/com/android/server/wm/Task.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) { // ...
boolean someActivityResumed = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
if (isLeafTask()) {
if (isFocusableAndVisible()) {
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
}
} else {
// ...
}
}
// ...
return someActivityResumed;
}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { return resumeTopActivityUncheckedLocked(prev, options, false / skipPause /); }
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
// Not ready yet!
return false;
}
// 任務棧棧頂正在執行的 Activity
final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
if (topActivity == null) {
// 空任務棧 There are no activities left in this task, let's look somewhere else.
return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
}
final boolean[] resumed = new boolean[1];
final TaskFragment topFragment = topActivity.getTaskFragment();
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
// ...
return resumed[0];
}
``` 在 Task 的 resumeTopActivityUncheckedLocked 方法中進而又呼叫了resumeTopActivityUncheckedLocked,在 resumeTopActivityInnerLocked 中通過 TaskFragment 呼叫了 resumeTopActivity,接著來看 TaskFragment 中的實現。
```java frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final ActivityTaskSupervisor mTaskSupervisor;
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options, boolean deferPause) { ActivityRecord next = topRunningActivity(true / focusableOnly /); // ...
if (mResumedActivity != null) {
// 暫停棧頂的Activity
pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */, next, "resumeTopActivity");
}
// ...
// 要啟動的 Activity 已存在,且不需要重新建立,例如設定了 singleTask 或 singleTop啟動模式
if (next.attachedToProcess()) {
// ...
ActivityRecord lastResumedActivity =
lastFocusedRootTask == null ? null
: lastFocusedRootTask.getTopResumedActivity();
final ActivityRecord.State lastState = next.getState();
mAtmService.updateCpuStats();
next.setState(RESUMED, "resumeTopActivity");
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order.
boolean notUpdated = true;
// ...
try {
// 開啟一個事務
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.token);
// ...
if (next.newIntents != null) {
// 新增 onNewIntent 的 callback ,最終會在APP端執行 onNewIntent()
transaction.addCallback(
NewIntentItem.obtain(next.newIntents, true /* resume */));
}
// ...
// 設定 Activity 最終的生命週期狀態為 Resume
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
dc.isNextTransitionForward()));
// Flag1:開始執行事務
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
} catch (Exception e) {
// ...
// Resume 異常,重新啟動
mTaskSupervisor.startSpecificActivity(next, true, false);
return true;
}
// ...
} else {
// ...
// 啟動 Activity
mTaskSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
``` resumeTopActivity 方法中主要做了兩件事情,如果要啟動的這個 Activity 已經存在,並且設定了像“singleInstance” 的啟動模式,無需重新建立 Activity 的情況下,則先通過 ClientTransaction 添加了一個 NewIntentItem 的 callback,接下來通過 setLifecycleStateRequest 設定了一個 ResumeActivityItem 物件。這裡的 ClientTransaction 是什麼? scheduleTransaction 又是做了什麼?這裡先不做探討,留一個Flag,後邊再來分析。
接著繼續看主線流程,在 next.attachedToProcess()
返回 false 之後,通過 ActivityTaskSupervisor 呼叫了 startSpecificActivity
,這裡是 Activity 正常啟動的流程,檢視 startSpecificActivity
原始碼如下:
```java frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
// ...
}
// ...
}
// ...
}
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException {
// ...
final Task task = r.getTask();
final Task rootTask = task.getRootTask();
try {
// ...
// 建立啟動 Activity 的事務
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.token);
final boolean isTransitionForward = r.isTransitionForward();
final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
// 新增啟動 Activity 的 callback,執行launchActivity
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
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));
// Activity 啟動後最終的生命週期狀態
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
// 將最終生命週期設定為 Resume 狀態
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
// 將最終生命週期設定為 Pause 狀態
lifecycleItem = PauseActivityItem.obtain();
}
// 設定 Activity 啟動後最終的生命週期狀態
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 開啟事務
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
// ...
} catch (RemoteException e) {
// ...
}
} finally {
// ...
}
// ...
return true;
}
``
startSpecificActivity方法中最核心的邏輯是呼叫了
realStartActivityLocked` ,這個方法中同樣是獲取了一個 ClientTransaction 並呼叫了它的 addCallback 方法,與上邊不同的是,這裡添加了一個 LaunchActivityItem 例項。
這裡與上邊 Flag 處的程式碼邏輯是一樣,只是設定的 callback 不同,那 ClientTransaction 是什麼?它與 Activity 的啟動又有什麼關係呢?
1. ClientTransaction
ClientTransaction 是包含了一系列要執行的事務項的事務。我們可以通過呼叫它的 addCallback
方法來新增一個事務項,你也可以多次呼叫來新增多個事務項。addCallback 接收的引數型別為 ClientTransactionItem,而這個 ClientTransactionItem 有多個子類,例如上邊已經出現過的 OnNewIntentItem、LaunchActivityItem 等都是其子類。
另外可以通過 ClientTransactionItem 的 setLifecycleStateRequest
方法設定 Activity 執行完後最終的生命週期狀態,其引數的型別為 ActivityLifecycleItem。而 ActivityLifecycleItem 也是繼承自 ClientTransactionItem。ActivityLifecycleItem 也有多個子類,它的每個子類都對應了 Activity 的一個生命週期。
在完成 callback 與 lifeCycleStateRequest 的設定之後,便通過呼叫 mService.getLifecycleManager().scheduleTransaction(clientTransaction)
方法開啟事務項的執行。
這裡的 mService.getLifecycleManager() 獲取到的是什麼呢?跟蹤 ActivityTaskManagerService 原始碼我們可以找到 getLifecycleManager 的程式碼如下:
```java // frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java private final ClientLifecycleManager mLifecycleManager;
ClientLifecycleManager getLifecycleManager() {
return mLifecycleManager;
}
``` 可以看到,getLifecycleManager 返回了一個 ClientLifecycleManager 的例項,並呼叫了 scheduleTransaction 方法,程式碼如下:
```java // frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); // ... }
``` 上述方法的核心程式碼是呼叫了 ClientTransaction 的 schedule 方法,schedule 方法原始碼如下:
```java // frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
private IApplicationThread mClient;
public void schedule() throws RemoteException { mClient.scheduleTransaction(this); } ```
在 schedule 方法中通過 mClient 呼叫了 scheduleTransaction, 這裡的 mClient 即為 IApplicationThread,也就是我們在第二章中提到的客戶端的 Binder。這個引數是在例項化 ClientTransaction 時傳進來的,IApplicationThread 是一個AIDL 類,那麼通過編譯後它會生成一個 IApplicationThread.Stub 類,上文中提到的 ActivityThread#ApplicationThread 就是繼承了IApplicationThread.Stub。
```java // frameworks/base/core/java/android/app/ActivityThread#ApplicationThread
private class ApplicationThread extends IApplicationThread.Stub { // ... }
``` 既然我們已經知道了 IApplicationThread 是客戶端 Binder 在服務端的代理, 那麼這裡實際上是就是呼叫了客戶端 ApplicationThread 中的 scheduleTransaction 方法。
至此,程式碼最終又回到了客戶端的 ApplicationThread 中。但是,關於 ClientTransaction 的分析到這裡還未結束。可以看到的是,此時的程式碼又通過 scheduleTransaction 方法回到了客戶端,並且將 ClientTransaction 作為引數傳回了過去。那麼,ClientTransaction 的執行邏輯實際上在客戶端中執行的。
四、再探客戶端的呼叫流程
通過 Binder IPC,程式碼的呼叫流程又回到了客戶端,來看 ApplicationThread 中 scheduleTransaction 方法的實現,原始碼如下:
```java // frameworks/base/core/java/android/app/ActivityThread#ApplicationThread
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
``` 這個方法中又呼叫了 ActivityThread 的 scheduleTransaction 。而 scheduleTransaction 的原始碼在ActivityThread 的父類 ClientTransactionHandler 中, 如下:
```java // frameworks/base/core/java/android/app/ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
```
這裡將 transaction 作為引數呼叫了 sendMessage 方法。sendMessage 方法原始碼如下:
```Java
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1) {
sendMessage(what, obj, arg1, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
// 設定非同步訊息,會優先執行
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
``
可以看到,這裡最終將 ClientTransaction 與 EXECUTE_TRANSACTION 打包成一個 Message ,並且將這個 Message 設定成了非同步訊息,最終通過 mH 傳送了出去,這裡的 mH 是一個繼承自 Handler 的
H` 類,位於 ActivityThread 類的內部。
Message 被設定為非同步訊息後具有優先執行權,因為 Activity 的啟動涉及到 Activity 的建立以及生命週期的呼叫,所有這裡傳送出來的 Message 不應該被其他 Message 阻塞,不然肯定會影響到 Activity 的啟動,造成卡頓問題。具體分析可以參見 《反思 Android 訊息機制的設計與實現》 這篇文章。
接下來看一下在 H 類的內部是如何處理這條訊息的,我們搜尋 EXECUTE_TRANSACTION
可以看到如下程式碼:
```java // frameworks/base/core/java/android/app/ActivityThread#H public void handleMessage(Message msg) { switch (msg.what) { case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); // ... break;
}
} ``` 這裡的程式碼很簡單,通過 Message 拿到 ClientTransaction 後,然後通過 TransactionExecutor 的 execute 方法來執行 ClientTransaction。
在上一章中,我們只是對 ClientTransaction 做了簡單的介紹。雖然 ClientTransaction 的例項化是在服務端,但其執行流程卻是在客戶端。看一下 TransactionExecutor 中 execute 原始碼:
```java // frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
// ...
// 執行 callback
executeCallbacks(transaction);
// 執行 lifecycleState
executeLifecycleState(transaction);
mPendingActions.clear();
}
``` 這個方法裡的執行邏輯可以分為兩部分: - 通過 executeCallbacks 方法執行所有被新增進來的 ClientTransactionItem - 通過 executeLifecycleState 方法將 Activity 的生命週期執行到指定的狀態
1. executeCallbacks 方法分析
executeCallbacks 方法中的邏輯比較簡單,其原始碼如下:
```java
public void executeCallbacks(ClientTransaction transaction) { // ...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
// ...
final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);
// ...
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
``` 在 executeCallbacks 中遍歷了所有的 ClientTransactionItem 並執行了 ClientTransactionItem 的 execute 方法。上一章我們分析了,當 Activity 正常啟動時,通過 addCallback 新增的是一個 LaunchActivityItem 的例項。以此為例,這裡就會首先執行 LaunchActivityItem 的 execute 方法來執行 Activity 的例項化及 onCreate 生命週期的呼叫,這塊原始碼留作後邊再來分析。
2. ClientTransactionItem
我們上文提到過 ClientTransactionItem 有多個實現類,這些實現類對應了 Activity 中不同的執行流程。例如在 Activity 啟動時如果不需要重新建立 Activity ,則會通過 addCallback 添加了一個 NewIntentItem 來執行 Activity 的 onNewIntennt 方法。而當需要重新建立 Activity 時,則傳入的是一個 LaunchActivityItem,用來建立並啟動Activity。
ClientTransactionItem 的所有子類或相關類均在 frameworks/base/core/java/android/app/servertransaction/ 目錄下,如下圖所示:
上文中提到的 ActivityLifecycleItem 繼承自 ClientTransactionItem ,且其子類均為 Activity 生命周相關的實現,例如,StartActivityItem、ResumeActivityItem、DestroyActivityItem 等。顯而易見的是,這裡將 Activity 的生命週期以及其它相關方法以面向物件的思想封裝成了一個個的物件來執行。相比早些年的 Android 版本程式碼,所有生命週期以及相關方法都通過 Handler 的 sendMessage 的方式傳送出來,這種面向物件的思想的邏輯更加清晰,且程式碼更容易維護。
3. executeLifecycleState 方法分析
接著來看 executeCallbacks 中的 executeLifecycleState 方法,前面提到過,這裡會將 Activity 執行到指定的生命週期狀態。上邊的程式碼中我們看到在 Activity 啟動時,setLifecycleStateRequest 設定的是一個 ResumeActivityItem,程式碼如下:
Java
// 設定 Activity 最終的生命週期狀態為 Resume
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
dc.isNextTransitionForward()));
設定了 ResumeActivityItem後,接下來的程式碼會怎麼執行呢?來看 executeLifecycleState
方法的原始碼:
```Java private void executeLifecycleState(ClientTransaction transaction) { final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); // ...
// 第二個引數為執行完時的生命周狀態
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
``
這段程式碼的關鍵點在於
cycleToPath` ,同時,通過 lifecycleItem.getTargetState() 作為結束時的生命週期狀態。由於此時設定的是一個 ResumeActivityItem,它的 getTargetState 返回的是一個 ON_RESUME 的值,程式碼如下:
```Java // frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java @Override public int getTargetState() { return ON_RESUME; }
@Retention(RetentionPolicy.SOURCE)
public @interface LifecycleState{}
public static final int UNDEFINED = -1;
public static final int PRE_ON_CREATE = 0;
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;
```
可以看到 ON_RESUME 的值為 3。接著來看 cycleToPath 原始碼:
```Java
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
// 獲取當前 Activity 的生命週期狀態,即開始時的狀態
final int start = r.getLifecycleState();
// 獲取要執行的生命週期陣列
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
// 按順序執行 Activity 的生命週期
performLifecycleSequence(r, path, transaction);
}
``` 在這個方法中,首先獲取了當前 Activity 生命週期狀態,即開始執行 getLifecyclePath 時 Activity 的生命週期狀態,由於 executeLifecycleState 方法是在 executeCallback 之後執行的,上面我們已經提到此時的 Activity 已經執行完了建立流程,並執行過了 onCreate 的生命週期。因此,這裡的 start 應該是 ON_CREATE 狀態,ON_CREATE 的值為 1。
那麼接下來,這裡的關鍵點就在於在於 getLifecyclePath 做了什麼。我們看一下原始碼:
```Java // frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) { if (start == UNDEFINED || finish == UNDEFINED) { throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state"); } if (start == ON_RESTART || finish == ON_RESTART) { throw new IllegalArgumentException( "Can't start or finish in intermittent RESTART state"); } if (finish == PRE_ON_CREATE && start != finish) { throw new IllegalArgumentException("Can only start in pre-onCreate state"); }
mLifecycleSequence.clear();
// Activity 啟動 時,執行到這裡的 start 狀態為 ON_CREATE,結束狀態為 ON_RESUME
if (finish >= start) {
if (start == ON_START && finish == ON_STOP) {
// A case when we from start to stop state soon, we don't need to go
// through the resumed, paused state.
mLifecycleSequence.add(ON_STOP);
} else {
// 會走到這裡的邏輯,將 ON_START 與 ON_RESUME 新增到陣列
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
} else { // finish < start, can't just cycle down
if (start == ON_PAUSE && finish == ON_RESUME) {
// Special case when we can just directly go to resumed state.
mLifecycleSequence.add(ON_RESUME);
} else if (start <= ON_STOP && finish >= ON_START) {
// Restart and go to required state.
// Go to stopped state first.
for (int i = start + 1; i <= ON_STOP; i++) {
mLifecycleSequence.add(i);
}
// Restart
mLifecycleSequence.add(ON_RESTART);
// Go to required state
for (int i = ON_START; i <= finish; i++) {
mLifecycleSequence.add(i);
}
} else {
// Relaunch and go to required state
// Go to destroyed state first.
for (int i = start + 1; i <= ON_DESTROY; i++) {
mLifecycleSequence.add(i);
}
// Go to required state
for (int i = ON_CREATE; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
}
// Remove last transition in case we want to perform it with some specific params.
if (excludeLastState && mLifecycleSequence.size() != 0) {
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
return mLifecycleSequence;
}
```
根據上邊分析,此時的 start 為 ON_CREATE(值為 1),而 finish 的值為 ON_RESUME(值為 2)。因此,執行完 getLifecyclePath 後,會得到一個包含了 ON_START 與 ON_RESUME 的陣列。 接下來看performLifecycleSequence
中的程式碼:
```Java /* Transition the client through previously initialized state sequence. / private void performLifecycleSequence(ActivityClientRecord r, IntArray path, ClientTransaction transaction) { final int size = path.size(); // 遍歷資料,執行 Activity 的生命周 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);
}
}
}
``
在
performLifecycleSequence方法中則是遍歷了這個陣列。因為此時的陣列中有隻有 ON_START 與 ON_RESUME 兩個值,因此,這裡並分別執行了
mTransactionHandler.handleStartActivity與
mTransactionHandler.handleResumeActivity`,即呼叫了 ApplicationThread 的 handleStartActivity 與 handleResumeActivity 來執行 Activity 的 onStart 與 onResume 的生命週期。
五、Activity 的建立與生命週期的執行
通過前面幾個章節的分析我們已經知道,Activity 的啟動是在服務端通過新增一個 LaunchActivityItem 到 ClientTransaction 中實現的,然後通過 IApplicationThread 跨程序將 ClientTransaction 傳到了客戶端來執行的。客戶端通過遍歷 ClientTransaction 中的所有 ClientTransactionItem,並執行了它的 execute 方法進而來執行 Activity 的建立過程。那接下來我們就來看一下 LaunchActivityItem 的 execute 方法呼叫後到底是如何執行的。
```Java // frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
@Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
mTaskFragmentToken);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
``
LaunchActivityItem 的 execute 方法呼叫了 ClientTransactionHandler 的
handleLaunchActivity`,而這裡的 ClientTransactionHandler 就是 ActivityThread。 ActivityThread 中 handleLaunchActivity 的原始碼如下:
```Java // frameworks/base/core/java/android/app/ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true;
// ...
// 初始化 WindowManagerGlobal
WindowManagerGlobal.initialize();
// 呼叫 performLaunchActivity 執行 Activity 的建立流程
final Activity a = performLaunchActivity(r, customIntent);
// ...
return a;
}
``` 在 handleLaunchActivity 方法中首先去初始化了 WindowManagerGlobal,緊接著呼叫了 performLaunchActivity 並返回了一個 Activity 例項,那麼 Activity 的例項化必定是在 performLaunchActivity 中完成的。
1. Activity 的例項化與 onCreate 的呼叫
看下 performLaunchActivity 的原始碼:
```Java // frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; // ...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 在 Instrumentation 中通過反射例項化 Activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
appContext.getAttributionSource());
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
// ... 省略後半部分執行 Activity 生命週期的程式碼
return activity;
}
``` 這個方法中的主要邏輯可以分為兩部分,第一部分是例項化 Activity;第二部分是呼叫 Activity 的 onCreate。由於程式碼比較長,這裡我們只截取了第一部分的程式碼。可以看到這裡通過 Instrumentation 的 newActivity 獲取到一個 Activity 例項,newActivity 的引數傳入了一個 ClassLoader 和 Activity 的 className,因此,這裡的例項化 Activity 的過程一定是通過反射實現的。看程式碼:
```java public Activity newActivity(Class<?> clazz, Context context, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException, IllegalAccessException { Activity activity = (Activity)clazz.newInstance(); ActivityThread aThread = null; // Activity.attach expects a non-null Application Object. if (application == null) { application = new Application(); } activity.attach(context, aThread, this, token, 0 / ident /, application, intent, info, title, parent, id, (Activity.NonConfigurationInstances)lastNonConfigurationInstance, new Configuration(), null / referrer /, null / voiceInteractor /, null / window /, null / activityCallback /, null /assistToken/, null /shareableActivityToken/); return activity; }
``` newActivity 中通過反射例項化了 Activity,接著呼叫了 Activity 的 attach 方法。
接下來看 performLaunchActivity 方法的後半部分的邏輯,例項化了 Activity 之後是如何呼叫 Activity 的 onCreate 生命週期的。
```Java private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; // ...
try {
// 獲取 Application
Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
// ...
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config =
new Configuration(mConfigurationController.getCompatConfiguration());
// ...
// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
// 再次執行 Activity 的 attach 方法
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.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
// 設定 Activity 主題
activity.setTheme(theme);
}
if (r.mActivityOptions != null) {
activity.mPendingOptions = r.mActivityOptions;
r.mActivityOptions = null;
}
activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
activity.mCalled = false;
// Assigning the activity to the record before calling onCreate() allows
// ActivityThread#getActivity() lookup for the callbacks triggered from
// ActivityLifecycleCallbacks#onActivityCreated() or
// ActivityLifecycleCallback#onActivityPostCreated().
r.activity = activity;
// 呼叫 Activity 的 onCreate 方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// ...
}
r.setState(ON_CREATE);
} catch (SuperNotCalledException e) {
// ...
}
return activity;
}
``` 上述方法中首先獲取 Activity 的 title 以及 Configuration 等相關引數,然後再次呼叫 Activity 的 attach 方法,並將這些引數傳入。接著通過 Instrumentation 執行了 Activity 的 performCreate 方法,程式碼如下:
```Java public void callActivityOnCreate(Activity activity, Bundle icicle) { prePerformCreate(activity); activity.performCreate(icicle); postPerformCreate(activity); }
``` 而 Activity 的 performCreate 方法中最終會呼叫 Activity 的 onCreate方法。至此,我們在 Activity 的 onCreate 方法中寫的邏輯才會被呼叫。performCreate 方法的程式碼這裡就不再貼出,有興趣的可以自行檢視。
2. onStart 方法的執行
在第四章的第 3 小節中,中我們已經分析了建立完 Activity 後如何執行後續的生命週期流程。我們知道 onStart 是通過 ActivityThread 的 handleStartActivity 來執行的,其原始碼如下:
```java // frameworks/base/core/java/android/app/ActivityThread.java
public void handleStartActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, ActivityOptions activityOptions) { final Activity activity = r.activity; if (!r.stopped) { throw new IllegalStateException("Can't start activity that is not stopped."); } if (r.activity.mFinished) { // TODO(lifecycler): How can this happen? return; }
unscheduleGcIdler();
if (activityOptions != null) {
activity.mPendingOptions = activityOptions;
}
// 呼叫 Activity 的 performStart 進而執行 onStart
activity.performStart("handleStartActivity");
// 將生命周狀態設定為 ON_START
r.setState(ON_START);
// ...
}
``` handleStartActivity 的邏輯比較簡單。最主要的邏輯就是呼叫了 Activity 的 performStart 方法,進而呼叫了 onStart 方法。這裡也不再貼出 performStart 方法的原始碼,感興趣的同學自行檢視。
3. onResume 方法的呼叫
onResume 方法是通過 ActivityThread 的 handleResumeActivity 來執行的,原始碼如下:
```java // frameworks/base/core/java/android/app/ActivityThread.java
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest, boolean isForward, boolean shouldSendCompatFakeFocus, String reason) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true;
// TODO Push resumeArgs into the activity for consideration
// skip below steps for double-resume and r.mFinish = true case.
if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
// ... 省略 Window 的新增邏輯
}
``` handleResumeActivity 方法中的邏輯比較複雜,但核心主要有兩點: - 呼叫 performResumeActivity 執行 onResume 的生命週期 - 將 decorView 新增到 Window 中
上述程式碼中我們省略了 decorView 新增到 Window 部分的程式碼,後邊再來分析。先來看 performResumeActivity,其原始碼如下:
```java public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest, String reason) {
if (r.activity.mFinished) {
// 如果 Activity 已經是finish狀態,直接return false
return false;
}
if (r.getLifecycleState() == ON_RESUME) {
// 如果已經是 Resume 狀態 直接return false,避免重複執行
return false;
}
try {
// ...
// 執行 Activity 的 performResume 進而執行 onResume
r.activity. performResume(r.startsNotResumed, reason);
r.state = null;
r.persistentState = null;
// 設定 Activity 的狀態 為 ON_RESUME
r.setState(ON_RESUME);
reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming");
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to resume activity "
+ r.intent.getComponent().toShortString() + ": " + e.toString(), e);
}
}
return true;
}
``` performResumeActivity 中先對 Activity 的狀態進行了判斷,如果狀態符合,則會呼叫 Activity 的 performResume 方法,進而執行 Activity 的 onResume。performResume 方法的原始碼不再貼出。
在完成了 performResume 的呼叫後,performResumeActivity 方法中接著執行了將 DecorView 新增到 Window 的過。程式碼如下
```java // frameworks/base/core/java/android/app/ActivityThread.java
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest, boolean isForward, boolean shouldSendCompatFakeFocus, String reason) { // ...
final Activity a = r.activity;
if (r.window == null && !a.mFinished && willBeVisible) {
// PhoneWindow
r.window = r.activity.getWindow();
// 獲取 DecorView
View decor = r.window.getDecorView();
// 先設定 DecorView 不可見
decor.setVisibility(View.INVISIBLE);
// 獲取 WindowManager
ViewManager wm = a.getWindowManager();
// 獲取 Window 的屬性引數
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
// ...
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 通過 WindowManager 將 DecorView新增到視窗
wm.addView(decor, l);
} else {
// The activity will get a callback for this {@link LayoutParams} change
// earlier. However, at that time the decor will not be set (this is set
// in this method), so no action will be taken. This call ensures the
// callback occurs with the decor set.
a.onWindowAttributesChanged(l);
}
}
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
} else if (!willBeVisible) {
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
// ...
}
``
可以看到,上述方法的的核心是
wm.addView(decor, l)` 這行程式碼,即通過 ViewManager 的 addView 方法將 DecorView 新增到了視窗中。視窗的新增過程會完成 DecorView 的佈局、測量與繪製。當完成視窗的新增後 Activity 的 View 才被被顯示出來,且有了寬高。這也是為什麼我們在 onResume 中是獲取不到 View 寬高的原因。
另外需要注意到是,將 View 新增到 Window 的過程也是一個相當複雜的過程,這個過程也多次涉及到跨程序呼叫。這也是為什麼在本文的開頭提到 Activity 啟動是一個數次跨程序呼叫的過程的原因。關於 Window 的新增過程,這裡就不再贅述了,後邊會單獨寫一篇文章來詳細分析 Window 的新增。
六、總結
通過本篇文章我們詳細的瞭解了 Activity 的啟動流程,雖然在開發中啟動一個 Activity 只需要我們呼叫一行程式碼,但通過追蹤原始碼我們發現 startActivity 方法的呼叫棧非常深,且中間涉及了兩次跨程序的呼叫,如果不瞭解 Binder 與 AIDL 是比較難以讀懂的。另外,由於 Activity 的啟動過程比較複雜,文章中不能面面俱到,忽略了很多支線邏輯,比如當 啟動 Activity 時,Activity 所在的程序不存在時的邏輯,本文章並沒有去分析,感興趣的同學可以自行檢視原始碼。