--- title: '四大組件 - Activity 啟動' disqus: kyleAlien --- 四大組件 - Activity 啟動 === 對於一般應用來說,我們會認為啟動應該是 onCreate() 函數,其實不然,它如同一般的 Java 程序,啟動於 main() 函數 在閱讀前需要有 **[Binder 基礎知識](https://hackmd.io/yNGrVdN-RtelUqYQgn9avg?view)**,[**參考文章**](https://juejin.cn/post/6994823348190445604) [**參考 1**](https://juejin.cn/post/6994823348190445604) [**參考 2**](https://juejin.cn/post/6856298463119409165#heading-4) [**參考 3 - Android 11 啟動**](https://blog.csdn.net/guojingbu/article/details/117259786) ## OverView of Content [TOC] ## 啟動 Activity 從我們最常使用的啟動 Context#startActivity 開始分析,看 AMS 是如何跳轉指定 Activity ```java= // 啟動指定 Activity void startBootActivity() { Intent i = new Intent(this, BootActivity.class); startActivity(i); // 從這裡開始分析 } ``` ### Activity 調用 ActivityTaskManagerService * 首先看看 Activity 類 UML 關係圖,可以發現,Activity 不會直接接觸到 ActivityTaskManagerService,而是透過 Instrumentation 呼叫 > ![](https://i.imgur.com/TLQrPH9.png) 1. [**Acitivty**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Activity.java)#startActivity 方法:最終都會導向 **Activity#`startActivityForResult` 方法** 再透過 Instrumentation 請求啟動 Activity * **其中有一個重點是它會傳入目前進程的 ApplicationThread**) * 另一個則是 `mToken` 參數,它代表了當前應用在 AMS 中 ActivityManager 的代表 ```java= // Activity.java public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, ...省略部分接口 { /*package*/ ActivityThread mMainThread; private Instrumentation mInstrumentation; @Override public void startActivity(Intent intent) { this.startActivity(intent, null); } @Override public void startActivity(Intent intent, @Nullable Bundle options) { if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN) && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) { ... 省略部分 } // @ 分析 startActivityForResult if (options != null) { startActivityForResult(intent, -1, options); } else { startActivityForResult(intent, -1); } } public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); // @ 追蹤 Instrumentation#execStartActivity 函數,mMainThread 就是 ActivityThread Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( // @ 查看 getApplicationThread 方法 this, mMainThread.getApplicationThread(), mToken, // 類型為 IBinder,ActivityRecord 的代理物件 this, intent, requestCode, options); ... 省略部分 } else { ... 省略部分 } } } // --------------------------------------------------------- // ActivityThread .java public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal { // 一個應用行程只有一個 final ApplicationThread mAppThread = new ApplicationThread(); public ApplicationThread getApplicationThread() { return mAppThread; } private class ApplicationThread extends IApplicationThread.Stub { ... 省略細節 } } ``` :::info * Acitivty 的請求都會通過 **Instrumentation** 類 (這個就算是一個 Hook),用來監控應用與系統 AMS 互動過程 ::: 2. [**Instrumentation**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Instrumentation.java)#execStartActivity 方法:最後在啟動了 [**ActivityTaskManager**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityTaskManager.java)#startActivity 方法 **取得代理類與 ATMS 進程通訊** (ATMS 屬於 SystemServer 進程),對 Binder 使用有興趣可以參考 [**AIDL 文章**](https://hackmd.io/6KE-mXHdQ_ekm5eQ5Iv90g?view) ```java= // Instrumentation.java public class Instrumentation { public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; ... 省略部分 try { ...省略部分 // 啟動了 ActivityTaskManager#startActivity 函數 // whoThread 就是 IApplicationThread int result = ActivityTaskManager.getService().startActivity(whoThread, who.getBasePackageName(), who.getAttributionTag(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); // 檢查 AMS 啟動 Activity 啟動結果的檢查 checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; } } ``` * Instrumentation 的行為主要是透過 [**ActivityTaskManager**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityTaskManagerService.java) 取得 Binder 代理類與 ActivityTaskManagerService 通訊 > ![](https://i.imgur.com/MPisqUv.png) :::success * **checkStartActivityResult 函數:** 檢查 AMS 回傳的結果 ```java= // Instrumentation.java public static void checkStartActivityResult(int res, Object intent) { if (!ActivityManager.isStartResultFatalError(res)) { return; } switch (res) { // 在 Android Manifest 沒有註冊 case ActivityManager.START_INTENT_NOT_RESOLVED: case ActivityManager.START_CLASS_NOT_FOUND: if (intent instanceof Intent && ((Intent)intent).getComponent() != null) throw new ActivityNotFoundException( "Unable to find explicit activity class " + ((Intent)intent).getComponent().toShortString() + "; have you declared this activity in your AndroidManifest.xml?"); throw new ActivityNotFoundException( "No Activity found to handle " + intent); // 權限禁止 case ActivityManager.START_PERMISSION_DENIED: throw new SecurityException("Not allowed to start activity " + intent); // 請求衝突 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: throw new AndroidRuntimeException( "FORWARD_RESULT_FLAG used while also requesting a result"); ... 省略部分 default: throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent); } } ``` ::: :::danger * 提醒 AIDL 部分由 ^1^ 共同接口 [**IActivityTaskManager.aidl**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/IActivityTaskManager.aidl)、^2^ Proxy 代理 (AIDL 自動生成)、^3^ Stub 實作 [**ActivityTaskManagerService**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityTaskManagerService.java) ::: > ![](https://i.imgur.com/DWiGmQz.png) 3. ActivityTaskManager 透過 Binder 機制最終就會到達 **系統進程** 的 [**ActivityTaskManagerService**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityTaskManagerService.java) (AIDL 的 Server 端) | 重點參數 | 說明 | | - | - | | caller | 呼叫者 | | intent | 準備呼叫的 Activity 資訊 | | resultTo | 呼叫者 在 AMS 中的 ActivityRecord | ```java= // ActivityTaskManagerService.java // SystemService 啟動的系統進程 // IActivityTaskManager.Stub 是 Service 端的實作 public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // IActivityTaskManager 是 IDE 自動生成類 @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) { // @ 分析 startActivityAsUser return startActivityAsUser(caller, // 呼叫者 IApplicationThread callingPackage, callingFeatureId, intent, // 準備呼叫的 Activity 資訊 resolvedType, resultTo, // 呼叫者 在 AMS 中的 ActivityRecord resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } } ``` > ![](https://i.imgur.com/MzUc0jl.png) ### ActivityStartController - 準備 ActivityStart * `startActivity` (使用者行程) -> Binder -> `startActivityAsUser` (系統行程),最後透過 [**ActivityStartController**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityStartController.java) 來起動指定的 Activity ```java= // ActivityTaskManagerService.java public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** * @call 呼叫者的 IBinder (就是應用行程的 Binder Server), * 對應的就是 ActivityThread#ApplicationThread (內部類) */ @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) { // @ 查看 startActivityAsUser return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } @Override public int startActivityAsUser(IApplicationThread caller, String callingPackage, /*省略部分參數*/) { // @ 查看 startActivityAsUser return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId, true /*validateIncomingUser*/); } private int startActivityAsUser(IApplicationThread caller, String callingPackage, /*省略部分參數*/) { assertPackageMatchesCallingUid(callingPackage); enforceNotIsolatedCaller("startActivityAsUser"); userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // obtainStarter 返回一個 ActivityStarter 類 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(); // 直接查看 ActivityStarter#execute 函數 } } ``` > 從 [**ActivityStartController**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityStartController.java) 可以取得複用 (obtain) 的 ActivityStarter 類 1. 這裡 ActivityStartController 有使用到 **工廠模式**,目標產生產品是 ActivityStarter 2. [**ActivityStarter**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java) 是使用 **Builder 模式**,可以設定需要請動 Activity 的選項 > ![](https://i.imgur.com/aWYxaY6.png) * ActivityStarter#**execute** 主要有兩個動作: 1. 判斷目標 Activity 是否是重量級 2. 執行 應用 (APP) 行程的啟動 Activity 請求 ```java= // ActivityStarter.java private final ActivityTaskSupervisor mSupervisor; // Request 是內部類 Request mRequest = new Request(); class ActivityStarter { int execute() { try { int res; if (mRequest.activityInfo == null) { // @ 分析 resolveActivity 方法 mRequest.resolveActivity(mSupervisor); } // 線程鎖 synchronized (mService.mGlobalLock) { ... 省略部分 // 下一小節會分析這兩個方法 // 1. 判斷目標 Activity 是否是重量級 res = resolveToHeavyWeightSwitcherIfNeeded(); if (res != START_SUCCESS) { return res; } // 2. 執行 activity 請求 res = executeRequest(mRequest); ... 省略部分 } } } static class Request { ActivityInfo activityInfo; void resolveActivity(ActivityTaskSupervisor supervisor) { ... // @ 分析 resolveIntent 方法 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId, 0 /* matchFlags */, computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid)); ... activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags, profilerInfo); } } } ``` * [**ActivityTaskSupervisor**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java)#resolveActivity:到 **==PackageManagerService 找到對應的 Acitiviy 資訊==(也就是 ActivityInfo)** :::success * ActivityInfo 相當於 `AndroidManifest.xml` 中的 activity 標籤 ::: ```java= // ActivityTaskSupervisor.java final ActivityTaskManagerService mService; ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags, int filterCallingUid) { try { ... 省略部分 final long token = Binder.clearCallingIdentity(); try { // 透過 PKMS 取得 ResolveInfo return mService.getPackageManagerInternalLocked().resolveIntent( intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true, filterCallingUid); } finally { Binder.restoreCallingIdentity(token); } } /* 省略 finally */ } ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, ProfilerInfo profilerInfo) { // ActivityInfo 在 ResolveInfo 內 final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null; ... return aInfo; } ``` > ![](https://i.imgur.com/ymSzGUC.png) * 從這裡可以看出 **ActivityTaskManagerServer 的功能有 ++啟動 Acitivty++、++查詢 PKMS 資料++** > ![](https://i.imgur.com/dCSQvar.png) ### ActivityStarter - 準備啟動 execute 1. ActivityStarter#**resolveToHeavyWeightSwitcherIfNeeded**:判斷目標 Activity 是否是重量級,若當前系統中已經存在的重量級進程,並且裡面有你要 Activity,就直接返回 若你將要啟動的 Activity 是重量級進程但不存在,那就會繼續往下執行賦予新 Intent ```java= // ActivityStarter.java private final ActivityTaskManagerService mService; /** * 如果這是一個重量級進程而已經有另一個不同的重量級進程在運行, * 則更新對重量級切換的請求 */ private int resolveToHeavyWeightSwitcherIfNeeded() { ... 省略部分 // 判斷是否已經啟動 final WindowProcessController heavy = mService.mHeavyWeightProcess; if (heavy == null || (heavy.mInfo.uid == mRequest.activityInfo.applicationInfo.uid && heavy.mName.equals(mRequest.activityInfo.processName)) ) { return START_SUCCESS; } ... 省略部分 // 創建新 Intent final Intent newIntent = new Intent(); if (mRequest.requestCode >= 0) { // Caller is requesting a result. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); } newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target)); heavy.updateIntentForHeavyWeightActivity(newIntent); newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, mRequest.activityInfo.packageName); newIntent.setFlags(mRequest.intent.getFlags()); newIntent.setClassName("android" /* packageName */, HeavyWeightSwitcherActivity.class.getName()); mRequest.intent = newIntent; ... 省略部分 return START_SUCCESS; } ``` 2. ActivityStarter#**executeRequest**:執行啟動 Activity 動作,以下執行的動作可以分為 ^1.^ 判斷 caller(呼叫者進程) 是否還存活 :::info 有可能調用者 (APP) 被系統殺掉、異常退出等等,這時候 caller 就會消失 ::: ^2.^ 處理 Intent flag 的 `FLAG_ACTIVITY_FORWARD_RESULT` :::info * `FLAG_ACTIVITY_FORWARD_RESULT` 具有跨越是傳遞功能,當啟用後,setResult 結果會返回到來源 Acitivty > ![](https://i.imgur.com/J4OisYn.png) ::: ^3.^ 判斷是否支持該 Intent (多個判斷) ^4.^ 透過 ActivityTaskManagerService、ActivityTaskSupervisor 判斷啟動權限 ^5.^ **創建 ActivityRecord 對象,並呼叫 startActivityUnchecked 方法** :::info 創建 ActivityRecord (新 Activity) ,記錄各種判斷結果 ::: ```java= // ActivityStarter.java private final ActivityTaskManagerService mService; private final ActivityTaskSupervisor mSupervisor; private int mLastStartActivityResult; private int executeRequest(Request request) { // 使用者 APP 行程 final IApplicationThread caller = request.caller; // Actiivty 相關訊息 ActivityInfo aInfo = request.activityInfo; // 該 Activity 所屬的 Task (Stack) Task inTask = request.inTask; // 1. 判斷 caller 是否存在 WindowProcessController callerApp = null; if (caller != null) { callerApp = mService.getProcessController(caller); if (callerApp != null) { callingPid = callerApp.getPid(); callingUid = callerApp.mInfo.uid; } else { // 調用者如果不存在則 START_PERMISSION_DENIED err = ActivityManager.START_PERMISSION_DENIED; } } ... 省略部分 ActivityRecord sourceRecord = null; // 啟動來源 ActivityRecord resultRecord = null; // 目標結果 if (resultTo != null) { sourceRecord = mRootWindowContainer.isInAnyStack(resultTo); ... Debug 訊息 if (sourceRecord != null) { if (requestCode >= 0 && !sourceRecord.finishing) { resultRecord = sourceRecord; } } } final int launchFlags = intent.getFlags(); // 2. FLAG_ACTIVITY_FORWARD_RESULT 具有跨越是傳遞功能 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { // 不能再使用 startActivityForResult 方法 if (requestCode >= 0) { // 否則會報 START_FORWARD_AND_REQUEST_CONFLICT 錯誤 SafeActivityOptions.abort(options); return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; } resultRecord = sourceRecord.resultTo; if (resultRecord != null && !resultRecord.isInStackLocked()) { resultRecord = null; } // 轉換 setResult 結果到 來源 Activity resultWho = sourceRecord.resultWho; requestCode = sourceRecord.requestCode; sourceRecord.resultTo = null; if (resultRecord != null) { resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); } if (sourceRecord.launchedFromUid == callingUid) { callingPackage = sourceRecord.launchedFromPackage; callingFeatureId = sourceRecord.launchedFromFeatureId; } } ... 省略部分 // 這裡只提部分 // 3. 判斷是否支持該 Intent if (err == ActivityManager.START_SUCCESS && aInfo == null) { err = ActivityManager.START_CLASS_NOT_FOUND; } if (err == ActivityManager.START_SUCCESS && sourceRecord != null && sourceRecord.getTask().voiceSession != null) { // 語音相關 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { try { intent.addCategory(Intent.CATEGORY_VOICE); // 語音 if (!mService.getPackageManager().activitySupportsIntent( intent.getComponent(), intent, resolvedType)) { Slog.w(TAG, "Activity being started in current voice task does not support " + "voice: " + intent); err = ActivityManager.START_NOT_VOICE_COMPATIBLE; } } catch (RemoteException e) { Slog.w(TAG, "Failure checking voice capabilities", e); err = ActivityManager.START_NOT_VOICE_COMPATIBLE; } } } ...省略部分 // 4. 必須經過三種判斷,判斷調用者是否有權限來啟動 Activity boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho, requestCode, /* 省略部份參數*/); abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, callingPid, resolvedType, aInfo.applicationInfo); abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid, callingPackage); boolean restrictedBgActivity = false; if (!abort) { try { restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, request.originatingPendingIntent, request.allowBackgroundActivityStart, intent); } /* 省略 finally */ } ... 省略部分 // 5. 創建 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; ... 省略部分 final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getRootTask(); // @ 分析 startActivityUnchecked 方法 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, restrictedBgActivity, intentGrants); ... return mLastStartActivityResult; } ``` > ![](https://i.imgur.com/JF2b7cD.png) * ActivityStarter 依賴 ActivityRecord#Builder,透過 Builder 模式來創建 ActivityRecord 對象,這個 Activity 中紀錄呼叫、目標 Activity :::info * 不同描述者會以不一樣的方式形容 Activity | 描述者 | 代表 Activity 類 | | -------- | -------- | | PKMS | ActivityInfo (AndroidManifest 內的節點訊息) | | AMS | ActivityRecord | ::: > ![](https://i.imgur.com/fwIa3dJ.png) ### [ActivityStarter](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityStarter.java) - Activity 啟動流程 :::info 提醒:目前還在系統行程 (SystemServer) 唷 ! ::: * 重點包括 1. 決定 Activity 目標 Task 2. 顯示 Activity 啟動動畫 3. 通知 RootWindowContainer 啟動 Acitivty 的 Window 視窗 * ActivityStarter UML | 類 | 說明 | 其他 | | -------- | -------- | -------- | | ActivityRecord | Activity 在 AMS 中的代表 | | | Task | 用鏈結串起 ActivityRecord | 之前有 Stack 管理,新版已移除 | | RootWindowContainer | 畫面管理 | | > ![](https://i.imgur.com/F8iXFoB.png) * 在 **executeRequest** 函數中,最後會呼叫到 **startActivityUnchecked** 方法,以下簡單說明這些方法的功能 | ActivityStarter 重點方法 | 功能 | | -------- | -------- | | executeRequest | 檢查權限、Caller (Client 端的 IBinder) 等等 | | startActivityUnchecked | 經過檢查後,準備啟動 Activity,**若啟動失敗也在負責移除** | | startActivityInner | 主要是對 Activity 棧的控制,可添加 Activity 到 stack 當中 or 通知 Intent | ```java= // ActivityStarter.java // executeRequest 呼叫該 Function private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants) { int result = START_CANCELED; final Task startedActivityRootTask; ... try { ... // @ 分析 startActivityInner 方法 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants); ... } finally { ... startedActivityRootTask = handleStartResult(r, result); ... } postStartActivityProcessing(r, result, startedActivityStack); return result; } ``` * [**ActivityStarter#startActivityInner**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityStarter.java#1588) 方法:如果沒設定其他 Flag,**最後就會啟動 Task#`startActivityLocked` 方法**,該方法有兩個重點 1. 定義 ActivityStarter 的 `mSourceRootTask`、`mTargetRootTask` 成員,決定 Activity 所屬的來源、目標棧 (Task) ```java= // ActivityStarter.java private Task mSourceRootTask; // 來源 private Task mTargetRootTask; // 啟動目標 ActivityRecord mStartActivity; private final ActivityTaskManagerService mService; private final RootWindowContainer mRootWindowContainer; int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, /* 省略部份*/ ) { ...省略部分 // 取得可重用的 Task final Task reusedTask = getReusableTask(); final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask(); // 是否創建新 Task final boolean newTask = targetTask == null; mTargetTask = targetTask; computeLaunchParams(r, sourceRecord, targetTask); // 判斷當前 ActivtyRecord 是否能在目標 Task 啟動 int startResult = isAllowedToStart(r, newTask, targetTask); if (startResult != START_SUCCESS) { return startResult; } // 如果是覆用 Task,則取得目標棧頂 Activity (尚未 finsih) final ActivityRecord targetTaskTop = newTask ? null : targetTask.getTopNonFinishingActivity(); if (targetTaskTop != null) { // 重複使用 Task startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants); if (startResult != START_SUCCESS) { return startResult; } } else { mAddingToTask = true; } ... if (mTargetRootTask == null) { mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions); } // 依照當前分析狀況,會啟動新 Task if (newTask) { final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) ? mSourceRecord.getTask() : null; // 設定新 Task setNewTask(taskToAffiliate); } else if (mAddingToTask) { addOrReparentStartingActivity(targetTask, "adding to task"); } ...省略部分 return START_SUCCESS; } ``` 2. 分析 Intent;設定 Activity 啟動畫面 `startActivityLocked`、啟動 Acitivty `resumeFocusedTasksTopActivities` ```java= // ActivityStarter.java private Task mSourceRootTask; private Task mTargetRootTask; ActivityRecord mStartActivity; private final ActivityTaskManagerService mService; private final RootWindowContainer mRootWindowContainer; int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, // 呼叫者 資訊 /* 省略部分參數 */) { ... // @ 1. 分析 Intent,設定 Activity 啟動畫面 (先分析) mTargetRootTask.startActivityLocked(mStartActivity, topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask, mKeepCurTransition, mOptions); if (mDoResume) { // 該 Activity 存在 final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetRootTask.isTopActivityFocusable() || (topTaskActivity != null && topTaskActivity.isTaskOverlay() && mStartActivity != topTaskActivity)) { // 如果沒有不可聚焦 (Fousable) 則無法回復 (resume), // 但仍會讓該 Activity 可見 // 也就是可見的 暫停 狀態 mTargetRootTask.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS); mTargetRootTask.mDisplayContent.executeAppTransition(); } else { // 若棧頂 Activity 不在焦點上,則將其移動到前面 if (mTargetRootTask.isTopActivityFocusable() && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) { mTargetRootTask.moveToFront("startActivityInner"); } // 2. @ 開始新的活動 (後分析) mRootWindowContainer.resumeFocusedTasksTopActivities( mTargetRootTask, mStartActivity, mOptions, mTransientLaunch); } } ... return START_SUCCESS; } ``` >![](https://i.imgur.com/3PJ9L4q.png) ### [Task](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/wm/Task.java) 分析 Intent - 添加 Activity 啟動畫面 * Task 類關係 > ![](https://i.imgur.com/BubT7aL.png) * [**Task**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/wm/Task.java)#**`startActivityLocked` 方法**:主要是 **判斷使用者設定的 Intent、設定 Activity 初始加載的畫面**,最後 **透過 AcitivtyRecord 來啟動 Activity 開始動畫** ```java= // TaskFragment.java class TaskFragment extends WindowContainer<WindowContainer> { final ActivityTaskSupervisor mTaskSupervisor; ... } // ------------------------------------------------------ // Task.java class Task extends TaskFragment { void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity, boolean newTask, boolean keepCurTransition, ActivityOptions options, @Nullable ActivityRecord sourceRecord) { Task rTask = r.getTask(); final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront(); final boolean isOrhasTask = rTask == this || hasChild(rTask); ... final Task activityTask = r.getTask(); if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) { mStackSupervisor.mUserLeaving = false; ... } task = activityTask; ... 省略 Debug 訊息 // The transition animation and starting window are not needed if {@code allowMoveToFront} // is false, because the activity won't be visible. if ((!isHomeOrRecentsStack() || hasActivity()) && allowMoveToFront) { final DisplayContent dc = getDisplay().mDisplayContent; ... 省略 Debug 訊息 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { // 無跳轉動畫 dc.prepareAppTransition(TRANSIT_NONE, keepCurTransition); // 添加無動畫 intent mStackSupervisor.mNoAnimActivities.add(r); } else { // 需要跳轉動畫 int transit = TRANSIT_ACTIVITY_OPEN; if (newTask) { if (r.mLaunchTaskBehind) { transit = TRANSIT_TASK_OPEN_BEHIND; } else if (getDisplay().isSingleTaskInstance()) { transit = TRANSIT_SHOW_SINGLE_TASK_DISPLAY; keepCurTransition = false; } else { if (canEnterPipOnTaskSwitch(focusedTopActivity, null /* toFrontTask */, r, options)) { focusedTopActivity.supportsEnterPipOnTaskSwitch = true; } transit = TRANSIT_TASK_OPEN; } } dc.prepareAppTransition(transit, keepCurTransition); mStackSupervisor.mNoAnimActivities.remove(r); } boolean doShow = true; if (newTask) { // 啟動一個新棧 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { resetTaskIfNeeded(r, r); doShow = topRunningNonDelayedActivityLocked(null) == r; } } else if (options != null && options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) { doShow = false; } if (r.mLaunchTaskBehind) { ... } else if (SHOW_APP_STARTING_PREVIEW && doShow) { ... // @ 追蹤 showStartingWindow 方法 // r 是 ActivityRecord r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity)); } } else { ... } } } ``` > ![](https://i.imgur.com/KSlv4qA.png) ### [RootWindowContainer](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java) 啟動棧頂 Activity * RootWindowContainer#**resumeFocusedTasksTopActivities** 方法:找到、並讓 Task 棧上的頂端 Activity 顯示 (**可聚焦 Focused 的 Activity**) ```java= // RootWindowContainer.java ActivityTaskSupervisor mTaskSupervisor; boolean resumeFocusedTasksTopActivities( Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) { // @ 追蹤 resumeFocusedTasksTopActivities return resumeFocusedTasksTopActivities(targetRootTask, target, targetOptions, false /* deferPause */); } boolean resumeFocusedTasksTopActivities( Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions, boolean deferPause) { if (!mTaskSupervisor.readyToResume()) { return false; } boolean result = false; if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea() || getTopDisplayFocusedRootTask() == targetRootTask)) { result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions, deferPause); } for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent display = getChildAt(displayNdx); final boolean curResult = result; boolean[] resumedOnDisplay = new boolean[1]; display.forAllRootTasks(rootTask -> { // 頂層 Activity final ActivityRecord topRunningActivity = rootTask.topRunningActivity(); if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) { return; } if (rootTask == targetRootTask) { // 已經在 resumed 狀態,不再 resumed resumedOnDisplay[0] |= curResult; return; } if (rootTask.getDisplayArea().isTopRootTask(rootTask) && topRunningActivity.isState(RESUMED)) { // Kick off any lingering app transitions form the MoveTaskToFront // operation, but only consider the top task and root-task on that // display. rootTask.executeAppTransition(targetOptions); } else { resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target); } }); result |= resumedOnDisplay[0]; if (!resumedOnDisplay[0]) { // 尚未啟動 // display 是 DisplayContent 對象 final Task focusedRoot = display.getFocusedRootTask(); if (focusedRoot != null) { // @ 繼續分析 resumeTopActivityUncheckedLocked 方法 result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions); } else if (targetRootTask == null) { // ... 找不到 Task,啟動 HomeActivity result |= resumeHomeActivity(null /* prev */, "no-focusable-task", display.getDefaultTaskDisplayArea()); } } } return result; } ``` * 先看看 Task & Window 的關係,^1.^ Task 關聯 ActivityRecord,並使用鏈結串起多個 Task,^2.^ ActivityRecord 又可以管理多個 Window 畫面 > ![](https://i.imgur.com/8kh5zYp.png) 1. 調用 [**Task**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/Task.java)#**resumeTopActivityUncheckedLocked** 函數,該目的在找到 Task 末端節點,並執行 `resumeTopActivityInnerLocked` 函數 ```java= // Task.java boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) { if (mInResumeTopActivity) { // Don't even start recursing. return false; } boolean someActivityResumed = false; try { // Protect against recursion. mInResumeTopActivity = true; // 找到末端節點 if (isLeafTask()) { if (isFocusableAndVisible()) { // 遞迴結束 & 發現可用 Activity 就啟動 // @ 分析 resumeTopActivityInnerLocked 方法 someActivityResumed = resumeTopActivityInnerLocked( prev, options, deferPause); } } else { int idx = mChildren.size() - 1; while (idx >= 0) { final Task child = (Task) getChildAt(idx--); // 找到 Top 並且可 Focus 的 Activity if (!child.isTopActivityFocusable()) { continue; } // 該 Task 不可見 if (child.getVisibility(null /* starting */) != TASK_VISIBILITY_VISIBLE) { break; } // 遞迴呼叫 resumeTopActivityUncheckedLocked 函數 someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options, deferPause); if (idx >= mChildren.size()) { idx = mChildren.size() - 1; } } } // 棧頂 Activity final ActivityRecord next = topRunningActivity(true /* focusableOnly */); if (next == null || !next.canTurnScreenOn()) { checkReadyForSleep(); } } finally { mInResumeTopActivity = false; } return someActivityResumed; } ``` 2. 找到目標葉節點後,**Task#resumeTopActivityInnerLocked 方法是啟動 Activity 的入口函數**,該函數會透過 `attachedToProcess` 判斷目標進程是否可連接 * 已啟動,則透過 `scheduleTransaction` 恢復 Activity * 未啟動,就透過 `startSpecificActivity` 啟動 Activity **==接下來會針對兩種狀態 (ActivityRecord 已存在、不存在) 進行分析==** > ![](https://i.imgur.com/lYi8ah0.png) ```java= // Task.java final ActivityTaskManagerService mAtmService; final ActivityTaskSupervisor mTaskSupervisor; private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) { ActivityRecord next = topRunningActivity(true /* focusableOnly */); ... 省略部分 // 判斷是否可以連接到 APP 進程 if(next.attachedToProcess()) { // 如果前一個活動是半透明的,則強制更新可見性,添加到 WM 的開啟應用列表中 final boolean lastActivityTranslucent = lastFocusedRootTask != null && (lastFocusedRootTask.inMultiWindowMode() || (lastFocusedRootTask.mLastPausedActivity != null && !lastFocusedRootTask.mLastPausedActivity.occludesParent())); if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) { // 設置為可見 next.setVisibility(true); } // schedule launch ticks to collect information about slow apps. next.startLaunchTickingLocked(); ActivityRecord lastResumedActivity = lastFocusedRootTask == null ? null : lastFocusedRootTask.getResumedActivity(); final ActivityState lastState = next.getState(); mAtmService.updateCpuStats(); ... 省略 Log // 設定 State 到 Resumed next.setState(RESUMED, "resumeTopActivityInnerLocked"); boolean notUpdated = true; ... 省略部分 try { // 要傳送給 Client 端的資訊 // next.appToken 就是目標應用的 ApplicationThread(Binder Server 類) final ClientTransaction transaction = ClientTransaction.obtain( next.app.getThread(), next.appToken ); // Deliver all pending results. ArrayList<ResultInfo> a = next.results; if (a != null) { final int N = a.size(); if (!next.finishing && N > 0) { ... 省略 Log 訊息 // 添加 callback // 注意 ActivityResultItem 在應用端會被呼叫 transaction.addCallback(ActivityResultItem.obtain(a)); } } if (next.newIntents != null) { transaction.addCallback( NewIntentItem.obtain(next.newIntents, true /* resume */)); } // 清除 應用的 停止狀態 next.notifyAppResumed(next.stopped); ... 省略 Log mAtmService.getAppWarningsLocked().onResumeActivity(next); ... 省略部分 transaction.setLifecycleStateRequest( ResumeActivityItem.obtain(next.app.getReportedProcState(), dc.isNextTransitionForward())); // @ 1. 分析 scheduleTransaction !! mAtmService.getLifecycleManager().scheduleTransaction(transaction); ... 省略 Log } catch (Exception e) { ... 省略部分 // 重新啟動 Activity mTaskSupervisor.startSpecificActivity(next, true, false); return true; } ... 省略部分 } else { ... 省略部分 // @ 2. 分析 startSpecificActivity, 啟動新 Activity mTaskSupervisor.startSpecificActivity(next, true, true); } return true; } ``` :::warning * Task 功能 1. 管理 ActivityRecord 2. 透過 Task 呼叫 ActivityTaskManagerService、ActivityTaskSupervisor 啟動 Activity ::: :::info * 這裡就使用到 APP 端的 ActivityTaskSupervisor 準備透過 ActivityTaskSupervisor 回 call 到 APP 端 ::: > ![](https://i.imgur.com/4OTNynn.png) ## 啟動已存在 Activity [**Task**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/Task.java)#resumeTopActivityInnerLocked 函數會判斷目標 ActivityRecord 是否已啟動,若已啟動則透過 `ClientLifecycleManager`#`scheduleTransaction` 恢復 Activity ### [ClientLifecycleManager](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ClientLifecycleManager.java) - scheduleTransaction 1. 第一步的重點在 **Binder Client & Server 的轉換**,這裡會透過 `ClientTransaction` 來呼叫 App 端的 BinderServer (就是 ActivityThread#ApplicationThread 類) ```java= // ClientLifecycleManager.java class ClientLifecycleManager { void scheduleTransaction(ClientTransaction transaction) throws RemoteException { // IApplicationThread 是應用端 final IApplicationThread client = transaction.getClient(); transaction.schedule(); if (!(client instanceof Binder)) { // 如果客戶端不是 Binder,這就是一個遠端調用,這個該對象就可以被回收 // 如果對象是 Binder 就由客戶(應用)端自己回收 transaction.recycle(); } } } ``` 2. [**ClientTransaction**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/servertransaction/ClientTransaction.java) 呼叫目標應用的 ApplicationThread (也就是目標應用的 BinderServer) ```java= // ClientTransaction.java /** Target client. */ private IApplicationThread mClient; // IApplicationThread 是目標應用的 BinderServer public void schedule() throws RemoteException { mClient.scheduleTransaction(this); } ``` > ![](https://i.imgur.com/YqF5Bji.png) ### ApplicationThread - scheduleTransaction 啟動 Activity :::info 由上一個步驟可以看到 AMS 透過 Binder (IApplicationThread) 呼叫到 APP 端的 BinderServer ::: 1. **ApplicationThread 是 [ActivityThread](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java) 的內部類,它實現了 Binder Server 的部分 (每個應用都有實現一個 ApplicationThread,是為了讓 AMS 有辦法操控 Activity)** ```java= // ActivityThread.java public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal { // 實現 AIDL 的 IApplicationThread.Stub 類 private class ApplicationThread extends IApplicationThread.Stub { @Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { // 查看 ClientTransactionHandler 父類 ActivityThread.this.scheduleTransaction(transaction); } } } ``` 2. 呼叫到 ActivityThread 的父類的 scheduleTransaction 方法 (也就是 [**ClientTransactionHandler**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ClientTransactionHandler.java),ClientTransactionHandler 負責處理 AMS 傳來的訊息) ```java= // ClientTransactionHandler.java public abstract class ClientTransactionHandler { // 準備啟動目標 Activity void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); // 主要看 sendMessage 函數 // 下面來看看傳入 EXECUTE_TRANSACTION 最終會如何處理 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } // 由 ActivityThread 實作 abstract void sendMessage(int what, Object obj); } ``` 3. ActivityThread 實作 sendMessage 方法,以啟動 Activity 來說就是對 Handler 傳入 `EXECUTE_TRANSACTION` 訊息,再由 [**TransactionExecutor**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/servertransaction/TransactionExecutor.java)#execute 函數處理 ```java= // ActivityThread.java final H mH = new H(); private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this); // H 是 Handler class H extends Handler { public static final int EXECUTE_TRANSACTION = 159; public void handleMessage(Message msg) { switch (msg.what) { ... 省略部分 case EXECUTE_TRANSACTION: // 對應 AMS 傳來的 ClientTransaction 對象 final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); if (isSystem()) { // 如果是系統進程則在 Client 端回收對象, // 而不是 ClientLifecycleManager 回收 // 避免在該函數訊息在被處理完之前就被回收 !! transaction.recycle(); } break; } } private void sendMessage(int what, Object obj, // EXECUTE_TRANSACTION int arg1, int arg2, boolean async) { ... 省略 Log 訊息 Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); } ``` 4. [**TransactionExecutor**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/servertransaction/TransactionExecutor.java)#execute 函數:執行所有 ClientTransactionItem (AMS 傳來) 的 execute 函數 ```java= // TransactionExecutor.java private ClientTransactionHandler mTransactionHandler; public void execute(ClientTransaction transaction) { ... 省略部分 // 分析 executeCallbacks executeCallbacks(transaction); executeLifecycleState(transaction); ... 省略部分 } public void executeCallbacks(ClientTransaction transaction) { final List<ClientTransactionItem> callbacks = transaction.getCallbacks(); ...省略部分 for (int i = 0; i < size; ++i) { // ClientTransactionItem 是抽象類,實作是 ActivityResultItem final ClientTransactionItem item = callbacks.get(i); ... 省略部分 item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); ... 省略部分 } } ``` > ![](https://i.imgur.com/6q07DuT.png) ### ActivityResultItem - execute 呼叫 Instrumentation * 這裡的 ClientTransactionItem 是抽象類,藉由傳入的對象不同,有不同的實作細節 (eg. execute 方法) :smiley: > ![](https://i.imgur.com/QG3wpLg.png) ```java= // ActivityResultItem.java public class ActivityResultItem extends ActivityTransactionItem { @Override public void execute(ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions) { // @ 分析 handleSendResult 方法 client.handleSendResult(r, mResultInfoList, "ACTIVITY_RESULT"); } } // --------------------------------------------------------------- // ActivityThread.java @Override public void handleSendResult(ActivityClientRecord r, List<ResultInfo> results, String reason) { final boolean resumed = !r.paused; if (!r.activity.mFinished && r.activity.mDecor != null && r.hideForNow && resumed) { updateVisibility(r, true); } if (resumed) { try { // Now we are idle. r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity); if (!r.activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPause()"); } } /*省略 catch*/ } checkAndBlockForNetworkAccess(); deliverResults(r, results, reason); if (resumed) { // 執行目標 ++ onResume ++ r.activity.performResume(false, reason); } } // --------------------------------------------------------------- // Activity.java final void performResume(boolean followedByPause, String reason) { ... 省略部分 // mResumed is set by the instrumentation mInstrumentation.callActivityOnResume(this); ... 省略部分 } ``` ### [Instrumentation](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Instrumentation.java) 呼叫 onResume * 最終可以看到 Activity#onResume 函數會透過 Instrumentation 呼叫 ```java= // /app/Instrumentation.java public void callActivityOnResume(Activity activity) { activity.mResumed = true; // 呼叫 Activity#onResume 函數 activity.onResume(); if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); am.match(activity, activity, activity.getIntent()); } } } } ``` > ![](https://i.imgur.com/YRf1uBg.png) ## 啟動新 Activity Task#resumeTopActivityInnerLocked 函數會判斷目標 ActivityRecord 是否已啟動,若已啟動則透過 `ActivityTaskSupervisor`#`startSpecificActivity` 啟動 Activity ### [ActivityTaskSupervisor](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java) - startSpecificActivity * 這裡的關鍵是在調用 `realStartActivityLocked` 函數,這裡會取用 ClientTransaction 對象,**透過 ActivityTaskManagerService 將 ClientTransaction 對象傳給目標 (要啟動的) Activity,之後該 Activity 會使用該對象** ```java= // ActivityTaskSupervisor.java final ActivityTaskManagerService mService 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 */ // If a dead object exception was thrown -- fall through to // restart the application. knownToBeDead = true; } ...省略部分 } boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException { ... 省略部分 try { ... 省略部分 try { // Create activity launch transaction. final ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken); final boolean isTransitionForward = r.isTransitionForward(); // 1. 添加 Callback 是一個重點 !! // 之後啟動的 Activity 會使用到 LaunchActivityItem 類 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.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken, r.getLaunchedFromBubble())); // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(isTransitionForward); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // 2. Schedule transaction. (繼續分析) mService.getLifecycleManager().scheduleTransaction(clientTransaction); ...省略部分 } /*省略 catch*/ ... 省略部分 } /*省略 catch*/ } ``` :::info * ActivityTaskManagerService 也是 AIDL 的 Server 端 ```java= // ActivityTaskManagerService.java public class ActivityTaskManagerService extends IActivityTaskManager.Stub { private final ClientLifecycleManager mLifecycleManager; ClientLifecycleManager getLifecycleManager() { return mLifecycleManager; } } ``` ::: * scheduleTransaction 函數如同上面小節分析,不另外再寫 這邊的重點在 **==LaunchActivityItem 類==,它與 Resume Activity 都使用同一個抽象對象(ClientTransactionItem),差異在實作細節** > ![](https://i.imgur.com/1Lex9er.png) ### [LaunchActivityItem](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/servertransaction/LaunchActivityItem.java) - execute 呼叫 Instrumentation * 這裡的 ClientTransactionItem 是抽象類,藉由傳入的對象不同,有不同的實作細節 :smiley: ```java= // LaunchActivityItem.java public class LaunchActivityItem extends ClientTransactionItem { @Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { ActivityClientRecord r = client.getLaunchingActivity(token); // handleLaunchActivity 是抽象方法 // ActivityThread 是它的實作類 client.handleLaunchActivity(r, pendingActions, null /* customIntent */); } } // ------------------------------------------------------------- // ActivityThread.java public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal { @Override public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... 省略部分 final Activity a = performLaunchActivity(r, customIntent); ... 省略部分 } } ``` * **ActivityThread#performLaunchActivity**: 創建 ContextImpl,透過 Instrumentation 類創建 Activity、Application 等等... 對象 ```java= // ActivityThread.java public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal { private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...省略部分 // 創建 Context ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { // 使用 Instrumentation 創建 Activity、Application 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 */ try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); ... 省略部分 if (activity != null) { ... 省略部分 // 呼叫 Activity#onCreate 函數 if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()"); } r.activity = activity; ... } } /* 省略 catch */ return activity; } } ``` > ![](https://i.imgur.com/sxLrAJn.png) ### [Instrumentation](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Instrumentation.java) - 創建 Activity、Application * Instrumentation#newActivity: 反射創建 Activity 對象 ```java= // Instrumentation.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 對象 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 /* activityConfigCallback */, null /*assistToken*/, null /*shareableActivityToken*/); return activity; } ``` ### [Instrumentation](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Instrumentation.java) - 呼叫 onCreate * ActivityThread#performLaunchActivity 函數會使用到 Instrumentation,並透過 Instrumentation 來呼叫 Activity#onCreate 函數 ```java= // Instrumentation.java public void callActivityOnCreate(Activity activity, Bundle icicle) { prePerformCreate(activity); // 呼叫 onCreate activity.performCreate(icicle); postPerformCreate(activity); } // ------------------------------------------------------------- // Activity.java final void performCreate(Bundle icicle) { performCreate(icicle, null); } final void performCreate(Bundle icicle, PersistableBundle persistentState) { if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:" + mComponent.getClassName()); } ... 省略部分 // 呼叫 onCreate 函數 if (persistentState != null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } ... 省略部分 } ``` > ![](https://i.imgur.com/DLSqeg1.png) ## [ActivityThread](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java) **真正的啟動類是 ActivitiyThread.java,它的內部就有我們所詳知的 main 方法,在這裡我們還可以看到 ^1^ Main 所使用的 Looper,並且啟動 Looper,令一個重點是 ^2^ ==attach 函數==** ```java= /** * ActivityThread.java * 路徑: ./frameworks/base/core/java/android/app/ActivityThread.java */ public static void main(String[] args) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); ...省略部份 // MainLooper Looper.prepareMainLooper(); // # prepare Main Looper ActivityThread thread = new ActivityThread(); thread.attach(false); //@ 追尋 attach if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); // # 啟動 Looper throw new RuntimeException("Main thread loop unexpectedly exited"); } ``` ### [ActivityThread](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java) - attach 開始連結 * 直接關注重點部份,也就是 attachApplication 函數,**Android 透過 Binder (不細講,需看另外一篇) 機制,取得代理器(ActivityManagerProxy)來呼叫到服務方跳轉到 ==ActivityManagerService 類==** ```java= // ActivityThread.java private void attach(boolean system) { // # main 傳入 false sCurrentActivityThread = this; mSystemThread = system; if (!system) { // View 管理器 ViewRootImpl.addFirstDrawHandler(new Runnable() { @Override public void run() { ensureJitEnabled(); } }); ...省略部份 // 取得 AMS 的代理對象,透過它與 AMS 溝通 final IActivityManager mgr = ... // # AIDL, Service Port try { // 傳入 Application mgr.attachApplication(mAppThread); // @ important ! Jamp to ActivityManagerService.class } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ...省略部份 } else { // SystemServer 才會傳入 true ...省略,因為 main 傳入的是 false } // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); // @ 註冊 View 管理器的 callBack ViewRootImpl.addConfigCallback(...); } ``` * 函數 attachApplication 也接收一個引數 `mAppThread`,它就是 ApplicationThread,在之後的綁定 Application 需要使用到 ### [ActivityManagerService](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/am/ActivityManagerService.java) 類 - attachApplication * AMS 類作為 AMS 的 Server 端,必須實現 IActivityManager.Stub 方法; attachApplication 函數相當長,它的重點在 1. bindApplication,綁定 App 端的 Application,也就是 App 端的 Binder,好讓 AMS 可以直接操控 Activity 2. ==**attachApplicationLocked**(連接 Activity)== ```java= // ActivityManagerService.java public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock { public ActivityTaskManagerInternal mAtmInternal; ... 省略其他函數 @Override public final void attachApplication(IApplicationThread thread, long startSeq) { if (thread == null) { throw new SecurityException("Invalid application interface"); } synchronized (this) { // 調用者的 PID int callingPid = Binder.getCallingPid(); // 調用者的 UID final int callingUid = Binder.getCallingUid(); // 把 PID/UID 設定為 AMS 的 PID/UID final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid, callingUid, startSeq); // 恢復為調用者的 PID/UID Binder.restoreCallingIdentity(origId); } } private boolean attachApplicationLocked(IApplicationThread thread, int pid) { try { ... 省略部分 // # 1. 綁定,這裡也是使用 Binder 機制,它會呼叫到 App 應用的 Service // 也就是呼叫到 ApplicationThread 中的 bindApplication thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked()); } /* 省略 catch */ ...省略 if (normalMode) { try { // @ 2. 連接 Activity if (mAtmInternal.attachApplication(app)) { didSomething = true; } } /* 省略 catch */ } } } ``` * bindApplication 會呼叫到 App 應用的 Service 去做綁定(也就是 ApplicationThread),但這邊先不關注這個,**先看 ==attachApplication==,它會 ++綁定需要的 Activity++、還有 ++啟動 Activity++ 種種的操作(先提出待會會使用到的兩個)** :::warning * Binder 安全性 帶有調用者的訊息,該訊息是系統設定,用來驗證調用者是否有權限調用 * Http 安全性 CS 架構中,使用應用層的設定的訊息,該訊息有可能有被竄改 ::: ### [ActivityTaskManagerInternal](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java) - 綁定&啟動 Activity * 在上面的 AMS 中會呼叫到 attachApplicationLocked#attachApplication 方法,而 ActivityTaskManagerInternal 類是抽象類,它的實作是 [**ActivityTaskManagerService**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/ActivityTaskManagerService.java)#內部類 LocalService ```java= // ActivityTaskManagerService.java public class ActivityTaskManagerService extends IActivityTaskManager.Stub { RootWindowContainer mRootWindowContainer; ... 省略部分 final class LocalService extends ActivityTaskManagerInternal { @Override public boolean attachApplication(WindowProcessController wpc) throws RemoteException { synchronized (mGlobalLockWithoutBoost) { // 省略 trace try { return mRootWindowContainer.attachApplication(wpc); } finally { ... 省略 trace } } } } } ``` * [**RootWindowContainer**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/wm/RootWindowContainer.java)#attachApplication ```java= // RootWindowContainer.java boolean attachApplication(WindowProcessController app) throws RemoteException { boolean didSomething = false; for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { mTmpRemoteException = null; mTmpBoolean = false; // Set to true if an activity was started. final DisplayContent display = getChildAt(displayNdx); display.forAllRootTasks(rootTask -> { if (mTmpRemoteException != null) { return; } if (rootTask.getVisibility(null /*starting*/) == TASK_VISIBILITY_INVISIBLE) { return; } // 查看 startActivityForAttachedApplicationIfNeeded 函數 final PooledFunction c = PooledLambda.obtainFunction( RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this, PooledLambda.__(ActivityRecord.class), app, rootTask.topRunningActivity()); rootTask.forAllActivities(c); c.recycle(); }); ...省略部分 } ...省略部分 return didSomething; } private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r, WindowProcessController app, ActivityRecord top) { ... 省略部分 try { if (mTaskSupervisor.realStartActivityLocked(r, app, top == r && r.isFocusable() /*andResume*/, true /*checkConfig*/)) { mTmpBoolean = true; } } /* 省略 catch */ return false; } ``` * **realStartActivityLocked 函數**: 在這邊會做一些啟動前的準備、校驗,準備好後使用 Binder 啟動呼叫 ApplicationThread 來啟動 Activity (還記得剛剛 App 端有把自身的 Binder 傳給 AMS 嗎? ) ```java= // RootWindowContainer.java final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { if (!allPausedActivitiesComplete()) { ...省略 Debug 訊息 return false; } if (andResume) { //# true r.startFreezingScreenLocked(app, 0); //# freez haven't start activity mWindowManager.setAppVisibility(r.appToken, true); // schedule launch ticks to collect information about slow apps. r.startLaunchTickingLocked(); // # cellection of app's data who start slowly } if (checkConfig) { // # true, check setting infomation Configuration config = mWindowManager.updateOrientationFromAppTokens( mService.mConfiguration, r.mayFreezeScreenLocked(app) ? r.appToken : null); mService.updateConfigurationLocked(config, r, false, true /* deferResume */); } // # ActivityRecord set data form the ProcessRecord 兩個都是傳近來的參數 r.app = app; app.waitingToKill = null; r.launchCount++; r.lastLaunchTime = SystemClock.uptimeMillis(); int idx = app.activities.indexOf(r); if (idx < 0) { app.activities.add(r); } mService.updateLruProcessLocked(app, true, null); mService.updateOomAdjLocked(); ... 省略部份 final ActivityStack stack = task.stack; try { ... 省略部份 //# if activity is home's, add it in this activity buttom of stack(如果是桌面 Activity,添加到當前 Activity 棧底) if (r.isHomeActivity()) { // Home process is the root process of the task. (本地流程是任務的根本流程) mService.mHomeProcess = task.mActivities.get(0).app; } ... 省略部份 // 往下追 scheduleLaunchActivity app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, //@ all params prepare done, ready start activity System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); } /* 省略 catch */ ``` ### App 端 - ApplicationThread * ApplicationThread ActivityThread 的私有內部類,並繼承於 ApplicationThreadNative(Binder Server),**它的主要功能在實現 ++IApplicationThread 接口++**,**==這裡就是 App 端實現的 Binder==** ```java= /** * AcitivtyThread.class */ public final class AcitivtyThread { /** * AcitivtyThread#ApplicationThread.class */ private class ApplicationThread extends ApplicationThreadNative { @Override public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); //# Inner Class record it r.token = token; r.ident = ident; r.intent = intent; r.referrer = referrer; r.voiceInteractor = voiceInteractor; r.activityInfo = info; r.compatInfo = compatInfo; r.state = state; r.persistentState = persistentState; r.pendingResults = pendingResults; r.pendingIntents = pendingNewIntents; r.startsNotResumed = notResumed; r.isForward = isForward; r.profilerInfo = profilerInfo; r.overrideConfig = overrideConfig; updatePendingConfiguration(curConfig); sendMessage(H.LAUNCH_ACTIVITY, r); //@ send message with activity start, call H.class } } } ``` 這裡有兩個地方要注意 1. 它創建了 ActivityClientRecord (是 ActivityThread 靜態內部類),用來紀錄所有有關這次啟動的訊息 2. 透過 Handler 機制傳送了 LAUNCH_ACTIVITY 訊息 ```java= /** * ActivityThread.class * 最呼叫到 外部 ActivityThread 的 sendMessage 方法 */ private void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { if (DEBUG_MESSAGES) Slog.v( TAG, "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj); Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); } /** * ActivityThread#H.class * 最終會呼叫到 ActivityThread 的私有內部類 H */ private class H extends Handler { public void handleMessage(Message msg) { switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); //@ 啟動 Activity handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; ...省略其他 } } /** * ActivityThread.class * handleLaunchActivity 主要是調用了 performLaunchActivity 方法 */ private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { ...省略部份 // Initialize before creating the activity WindowManagerGlobal.initialize(); Activity a = performLaunchActivity(r, customIntent); //@ prerform launch activity ...省略部份 } ``` ### performLaunchActivity - 創建 Activity * performLaunchActivity 函數存在於 ActivityThread 這個類中,主要的功能都會在這裡創建、綁定(Application, Context) ```java= /** * ActivityThread.class */ 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); } ComponentName component = r.intent.getComponent(); if (component == null) { // # 設定預設 Componect component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } // 創建 Activity 引用,準備回傳 Activity activity = null; try { // 獲取 LoadedApk - class, packageInfo is LoadedApk java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); // 使用 反射調用- 創建 Activity activity = mInstrumentation.newActivity( //# reflection create cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); 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); } } try { // packageInfo is LoadedApk Application app = r.packageInfo.makeApplication(false, mInstrumentation); //# get appliction object ...省略部份 if (activity != null) { // # createBaseContextForActivity 方法會返回 ContextImpl 類 Context appContext = createBaseContextForActivity(r, activity); ...省略部份 Window window = null; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null; r.mPendingRemoveWindowManager = null; } // # 將 Application & Context 綁定到 Activity 對象 ! activity.attach(appContext, this, getInstrumentation(), r.token, // # let appliction & context bind on activity r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window); if (customIntent != null) { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); if (theme != 0) { activity.setTheme(theme); } activity.mCalled = false; if (r.isPersistable()) { // @ 調用 Activity 的 onCreate 方法! mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ...省略部份 } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to start activity " + component + ": " + e.toString(), e); } } return activity; } ``` ### Instrumentation - onCreate 呼叫 * **Instrumentation 是連接 ActivityThread & Activity 中間的橋樑**,之後就可以連接到我們所使用的 onCreate 函數 ```java= //ActivityThread.class private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... if (r.isPersistable()) { // @ 調用 Activity 的 onCreate 方法! mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ... } /** * Instrumentation.class * callActivityOnCreate 接收 ActivityThread 所創建的 Activity, * 並透過 Instrumentation 與 Activity 連結 */ public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); activity.performCreate(icicle, persistentState); postPerformCreate(activity); } // ---------------------------------------------------------------- // Activity.class public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2, Window.OnWindowDismissedCallback, WindowControllerCallback { ... 省略其他 Activity 函數 final void performCreate(Bundle icicle, PersistableBundle persistentState) { restoreHasCurrentPermissionRequest(icicle); onCreate(icicle, persistentState); mActivityTransitionState.readState(icicle); performCreateCommon(); } public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { onCreate(savedInstanceState); } // 最終我們覆寫 onCreate 的地方! @MainThread @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); if (mLastNonConfigurationInstances != null) { mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders); } if (mActivityInfo.parentActivityName != null) { if (mActionBar == null) { mEnableDefaultActionBarUp = true; } else { mActionBar.setDefaultDisplayHomeAsUpEnabled(true); } } if (savedInstanceState != null) { Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG); mFragments.restoreAllState(p, mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.fragments : null); } mFragments.dispatchCreate(); getApplication().dispatchActivityCreated(this, savedInstanceState); if (mVoiceInteractor != null) { mVoiceInteractor.attachActivity(this); } mCalled = true; } } ``` ### 整體時序圖 > ![](https://i.imgur.com/LWPt3jK.png) ## Appendix & FAQ :::info ::: ###### tags: `Android Framework`