前言
Activity作為Android四大組件之一,他的啟動絕對沒有那么簡單,這里涉及到了系統服務行程,啟動程序細節很多,這里我只展示主體流程,activity的啟動流程隨著版本的更替,代碼細節一直在進行更改,每次都會有很大的修改,如android5.0 android8.0,我這里的版本是基于android api28,也是目前我可以查得到的最新原始碼了,事實上大題的流程是相同的,掌握了一個版本,其他的版本通過原始碼也可以很快地掌握,
因為涉及到不同的行程之間的通信:系統服務行程和本地行程,在最新版本的android使用的是AIDL來跨行程通信,所以需要對AIDL有一定的了解,會幫助理解整個啟動流程,
原始碼部分的講解涉及到很多的代碼講解,可能會有一點不適,但還是建議看完原始碼,原始碼的關鍵代碼處我都會加上注釋,方便理解,
代碼不會過分關注細節,只注重整體流程,想知道具體細節可以去查看原始碼,每份代碼所在的路徑我都會在代碼前面標注出來,各位可以去查看相對應的原始碼,
每部分原始碼前我都會放流程圖,一定要配合流程圖食用,不然可能會亂,
整體流程概述
這一部分側重于對整個啟動流程的概述,在心中有大體的概念,這樣可以幫助對下面具體細節流程的理解,
普通Activity的創建
普通Activity創建也就是平常我們在代碼中采用startActivity(Intent intent)方法來創建Activity的方式,總體流程如下圖:
啟動程序設計到兩個行程:本地行程和系統服務行程,本地行程也就是我們的應用所在行程,系統服務行程為所有應用共用的服務行程,整體思路是:
-
activity向Instrumentation請求創建
-
Instrumentation通過AMS在本地行程的IBinder介面,訪問AMS,這里采用的跨行程技術是AIDL,
-
然后AMS行程一系列的作業,如判斷該activity是否存在,啟動模式是什么,有沒有進行注冊等等,
-
通過ClientLifeCycleManager,利用本地行程在系統服務行程的IBinder介面直接訪問本地ActivityThread,
ApplicationThread是ActivityThread的內部類,IApplicationThread是在遠程服務端的Binder介面
-
ApplicationThread接收到服務端的事務后,把事務直接轉交給ActivityThread處理,
-
ActivityThread通過Instrumentation利用類加載器進行創建實體,同時利用Instrumentation回呼activity的生命中周期
這里涉及到了兩個行程,本地行程主要負責創建activity以及回呼生命周期,服務行程主要判斷該activity是否合法,是否需要創建activity堆疊等等,行程之間就涉及到了行程通信:AIDL,(如果不熟悉可以先去了解一下,但可以簡單理解為介面回呼即可)
下面介紹幾個關鍵類:
-
Instrumentation是activity與外界聯系的類(不是activity本身的統稱外界,相對activity而言),activity通過Instrumentation來請求創建,ActivityThread通過Instrumentation來創建activity和呼叫activity的生命周期,
-
ActivityThread,每個應用程式唯一一個實體,負責對Activity創建的管理,而ApplicationThread只是應用程式和服務端行程通信的類而已,只負責通信,把AMS的任務交給ActivityThread,
-
AMS,全稱ActivityManagerService,負責統籌服務端對activity創建的流程,
其他的類,后面的原始碼決議會詳解,
根Activity的創建
根Activity也就是我們點擊桌面圖示的時候,應用程式第一個activity啟動的流程,這里我側重講解多個行程之間的關系,下面的原始碼也不會講細節,只講解普通activity的創建流程,這里也相當于一個補充,先看整體流程圖:
主要涉及四個行程:
- Launcher行程,也就是桌面行程
- 系統服務行程,AMS所在行程
- Zygote行程,負責創建行程
- 應用程式行程,也就是即將要啟動的行程
主要流程:
- Launcher行程請求AMS創建activity
- AMS請求Zygote創建行程,
- Zygote通過fork自己來創建行程,并通知AMS創建完成,
- AMS通知應用行程創建根Activity,
和普通Activity的創建很像,主要多了創建行程這一步,
原始碼講解
Activity請求AMS的程序
流程圖
原始碼
-
系統通過呼叫Launcher的startActivitySafely方法來啟動應用程式,Launcher是一個類,負責啟動根Activity,
這一步是根Activity啟動才有的流程,普通啟動是沒有的,放在這里是作為一點補充而已
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java/; public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { //這里呼叫了父類的方法,繼續查看父類的方法實作 boolean success = super.startActivitySafely(v, intent, item); ... return success; }packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.java/; public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { ... // Prepare intent //設定標志singleTask,意味著在新的堆疊打開 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (v != null) { intent.setSourceBounds(getViewBounds(v)); } try { boolean isShortcut = Utilities.ATLEAST_MARSHMALLOW && (item instanceof ShortcutInfo) && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) && !((ShortcutInfo) item).isPromise(); //下面注釋1和注釋2都是直接采用startActivity進行啟動,注釋1會做一些設定 //BaseDraggingActivity是繼承自BaseActivity,而BaseActivity是繼承自Activity //所以直接就跳轉到了Activity的startActivity邏輯, if (isShortcut) { // Shortcuts need some special checks due to legacy reasons. startShortcutIntentSafely(intent, optsBundle, item);//1 } else if (user == null || user.equals(Process.myUserHandle())) { // Could be launching some bookkeeping activity startActivity(intent, optsBundle);//2 } else { LauncherAppsCompat.getInstance(this).startActivityForProfile( intent.getComponent(), user, intent.getSourceBounds(), optsBundle); } ... } ... return false; } -
Activity通過Instrumentation來啟動Activity
/frameworks/base/core/java/android/app/Activity.java/; public void startActivity(Intent intent, @Nullable Bundle options) { //最終都會跳轉到startActivityForResult這個方法 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) { //mParent是指activityGroup,現在已經采用Fragment代替,這里會一直是null //下一步會通過mInstrumentation.execStartActivity進行啟動 if (mParent == null) { options = transferSpringboardActivityOptions(options); Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);//1 if (ar != null) { mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } ... } ... } -
Instrumentation請求AMS進行啟動,該類的作用是監控應用程式和系統的互動,到此為止,任務就交給了AMS了,AMS進行一系列處理后,會通過本地的介面IActivityManager來進行回呼啟動activity,
/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) { ... //這個地方比較復雜,先說結論,下面再進行解釋 //ActivityManager.getService()獲取到的物件是ActivityManagerService,簡稱AMS //通過AMS來啟動activity,AMS是全域唯一的,所有的活動啟動都要經過他的驗證,運行在獨立的行程中 //所以這里是采用AIDL的方式進行跨行程通信,獲取到的物件其實是一個IBinder介面 //注釋2是進行檢查啟動結果,如果例外則拋出,如沒有注冊, try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); int result = ActivityManager.getService() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);//1 checkStartActivityResult(result, intent);//2 } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }這一步是通過AIDL技術進行跨進行通信,拿到AMS的代理物件,把啟動任務交給了AMS,
/frameworks/base/core/java/android/app/ActivityManager.java/; //單例類 public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { //得到AMS的IBinder介面 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); //轉化成IActivityManager物件,遠程服務實作了這個介面,所以可以直接呼叫這個 //AMS代理物件的介面方法來請求AMS,這里采用的技術是AIDL final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
AMS處理請求的程序
流程圖
原始碼
-
接下來看AMS的實作邏輯,AMS這部分的原始碼是通過ActivityStartController來創建一個ActivityStarter,然后把邏輯都交給ActivityStarter去執行,ActivityStarter是android 7.0加入的類,
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java/; //跳轉到startActivityAsUser //注意最后多了一個引數UserHandle.getCallingUserId(),表示呼叫者權限 public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { enforceNotIsolatedCaller("startActivity"); userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // TODO: Switch to user app stacks here. //這里通過ActivityStartController獲取到ActivityStarter,通過ActivityStarter來 //執行啟動任務,這里就把任務邏輯給到了AcitivityStarter return mActivityStartController.obtainStarter(intent, "startActivityAsUser") .setCaller(caller) .setCallingPackage(callingPackage) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setMayWait(userId) .execute(); }ActivityStartController獲取ActivityStarter
/frameworks/base/services/core/java/com/android/server/am/ActivityStartController.java/; //獲取到ActivityStarter物件,這個物件僅使用一次,當他的execute被執行后,該物件作廢 ActivityStarter obtainStarter(Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); } -
這部分主要是ActivityStarter的原始碼內容,涉及到的原始碼非常多,AMS把整個啟動邏輯都丟給ActivityStarter去處理了,這里主要做啟動前處理,創建行程等等,
/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java/; //這里需要做啟動預處理,執行startActivityMayWait方法 int execute() { try { ... if (mRequest.mayWait) { return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, mRequest.intent, mRequest.resolvedType, mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, mRequest.requestCode, mRequest.startFlags, mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId, mRequest.inTask, mRequest.reason, mRequest.allowPendingRemoteAnimationRegistryLookup); } ... } ... } //啟動預處理 private int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup) { ... //跳轉startActivity final ActivityRecord[] outRecord = new ActivityRecord[1]; int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason, allowPendingRemoteAnimationRegistryLookup); } //記錄啟動行程和activity的資訊 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) { ... //得到Launcher行程 ProcessRecord callerApp = null; if (caller != null) { callerApp = mService.getRecordForAppLocked(caller); ... } ... //記錄得到的activity資訊 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, checkedOptions, sourceRecord); if (outActivity != null) { outActivity[0] = r; } ... mController.doPendingActivityLaunches(false); //繼續跳轉 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); } //跳轉startActivityUnchecked private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { int result = START_CANCELED; try { mService.mWindowManager.deferSurfaceLayout(); //跳轉 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); } ... return result; } //主要做與堆疊相關的邏輯處理,并跳轉到ActivityStackSupervisor進行處理 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ... int result = START_SUCCESS; //這里和我們最初在Launcher設定的標志FLAG_ACTIVITY_NEW_TASK相關,會創建一個新堆疊 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { newTask = true; result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack); } ... if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { ... } else { if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) { mTargetStack.moveToFront("startActivityUnchecked"); } //跳轉到ActivityStackSupervisor進行處理 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } } } -
ActivityStackSupervisor主要負責做activity堆疊的相關作業,會結合ActivityStack來進行作業,主要判斷activity的狀態,是否處于堆疊頂或處于停止狀態等
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java/; boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { ... //判斷要啟動的activity是不是出于停止狀態或者Resume狀態 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || !r.isState(RESUMED)) { mFocusedStack.resumeTopActivityUncheckedLocked(null, null); } else if (r.isState(RESUMED)) { // Kick off any lingering app transitions form the MoveTaskToFront operation. mFocusedStack.executeAppTransition(targetOptions); } return false; } -
ActivityStack主要處理activity在堆疊中的狀態
/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java/; //跳轉resumeTopActivityInnerLocked boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { if (mStackSupervisor.inResumeTopActivity) { // Don't even start recursing. return false; } boolean result = false; try { // Protect against recursion. mStackSupervisor.inResumeTopActivity = true; //跳轉resumeTopActivityInnerLocked result = resumeTopActivityInnerLocked(prev, options); ... } finally { mStackSupervisor.inResumeTopActivity = false; } return result; } //跳轉到StackSupervisor.startSpecificActivityLocked,注釋1 @GuardedBy("mService") private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { ... if (next.app != null && next.app.thread != null) { ... } else { ... mStackSupervisor.startSpecificActivityLocked(next, true, true);//1 } if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true; } -
這里又回到了ActivityStackSupervisor,判斷行程是否已經創建,未創建拋出例外,然后創建事務交回給本地執行,這里的事務很關鍵,Activity執行的作業就是這個事務,事務的內容是里面的item,所以要注意下面的兩個item,
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java/; void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { //得到即將啟動的activity所在的行程 ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); getLaunchTimeTracker().setLaunchTime(r); //判斷該行程是否已經啟動,跳轉realStartActivityLocked,真正啟動活動 if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig);//1 return; } ... } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); } //主要創建事務交給本地執行 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ... //創建啟動activity的事務ClientTransaction物件 // Create activity launch transaction. final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); // 添加LaunchActivityItem,該item的內容是創建activity 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.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, mService.isNextTransitionForward(), profilerInfo)); // Set desired final state. //添加執行Resume事務ResumeActivityItem,后續會在本地被執行 final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // 通過ClientLifecycleManager來啟動事務 // 這里的mService就是AMS // 記住上面兩個item:LaunchActivityItem和ResumeActivityItem,這是事務的執行單位 // Schedule transaction. mService.getLifecycleManager().scheduleTransaction(clientTransaction); }通過AMS獲取ClientLifecycleManager
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java/; //通過AMS獲取ClientLifecycleManager ClientLifecycleManager getLifecycleManager() { return mLifecycleManager; } -
ClientLifecycleManager是事務管理類,負責執行事務
/frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); //執行事務 transaction.schedule(); if (!(client instanceof Binder)) { transaction.recycle(); } } -
把事務交給本地ActivityThread執行,這里通過本地ApplicationThread在服務端的介面IApplicationThread來進行跨行程通信,后面的邏輯就回到了應用程式行程了,
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java/; //這里的IApplicationThread是要啟動行程的IBinder介面 //ApplicationThread是ActivityThread的內部類,IApplicationThread是IBinder代理介面 //這里將邏輯轉到本地來執行 private IApplicationThread mClient; public void schedule() throws RemoteException { mClient.scheduleTransaction(this); }
ActivityThread創建Activity的程序
流程圖
原始碼
-
IApplicationThread介面的本地實作類ActivityThread的內部類ApplicationThread
/frameworks/base/core/java/android/app/ActivityThread.java/ApplicationThread.class/; //跳轉到ActivityThread的方法實作 public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { ActivityThread.this.scheduleTransaction(transaction); } -
ActivityThread執行事務,ActivityThread是繼承ClientTransactionHandler,scheduleTransaction的具體實作是在ClientTransactionHandler實作的,這里的主要內容是把事務發送給ActivityThread的內部類H去執行,H是一個Handle,通過這個Handle來切到主執行緒執行邏輯,
/frameworks/base/core/java/android/app/ClientTransactionHandler.java void scheduleTransaction(ClientTransaction transaction) { //事務預處理 transaction.preExecute(this); //這里很明顯可以利用Handle機制切換執行緒,下面看看這個方法的實作 //該方法的具體實作是在ActivityThread,是ClientTransactionHandler的抽象方法 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } /frameworks/base/core/java/android/app/ActivityThread.java/; final H mH = new H(); 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); } //利用Handle進行切換,mH是H這個類的實體 mH.sendMessage(msg); } -
H對事務進行處理,呼叫事務池來處理事務
/frameworks/base/core/java/android/app/ActivityThread.java/H.class //呼叫事務池對事務進行處理 public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { ... case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; //呼叫事務池對事務進行處理 mTransactionExecutor.execute(transaction); if (isSystem()) { transaction.recycle(); } // TODO(lifecycler): Recycle locally scheduled transactions. break; ... } ... } -
事務池對事務進行處理,事務池會把事務中的兩個item拿出來分別執行,這兩個事務就是上面我講的兩個Item,對應不同的初始化作業,
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java public void execute(ClientTransaction transaction) { final IBinder token = transaction.getActivityToken(); log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token); //執行事務 //這兩個事務就是當時在ActivityStackSupervisor中添加的兩個事件(第8步) //注釋1執行activity的創建,注釋2執行activity的視窗等等并呼叫onStart和onResume方法 //后面主要深入注釋1的流程 executeCallbacks(transaction);//1 executeLifecycleState(transaction);//2 mPendingActions.clear(); log("End resolving transaction"); } public void executeCallbacks(ClientTransaction transaction) { ... //執行事務 //這里的item就是當初添加的Item,還記得是哪個嗎? // 對了就是LaunchActivityItem item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); ... } private void executeLifecycleState(ClientTransaction transaction) { ... // 和上面的一樣,執行事務中的item,item型別是ResumeActivityItem lifecycleItem.execute(mTransactionHandler, token, mPendingActions); lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); } -
LaunchActivityItem呼叫ActivityThread執行創建邏輯,
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java/; public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client); // ClientTransactionHandler是ActivityThread實作的介面,具體邏輯回到ActivityThread client.handleLaunchActivity(r, pendingActions, null /* customIntent */); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } -
ActivityThread執行Activity的創建,主要利用Instrumentation來創建activity和回呼activity的生命周期,并創建activity的背景關系和app背景關系(如果還沒創建的話),
/frameworks/base/core/java/android/app/ActivityThread.java/; public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... // 跳轉到performLaunchActivity final Activity a = performLaunchActivity(r, customIntent); ... } //使用Instrumentation去創建activity回呼生命周期 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { //獲取ActivityInfo,用戶存盤代碼、AndroidManifes資訊, ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { //獲取apk描述類 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } // 獲取activity的包名型別資訊 ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } ... // 創建context背景關系 ContextImpl appContext = createBaseContextForActivity(r); // 創建activity Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); // 通過Instrumentation來創建活動 activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } ... try { // 根據包名創建Application,如果已經創建則不會重復創建 Application app = r.packageInfo.makeApplication(false, mInstrumentation); ... // 為Activity添加window Window window = null; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null; r.mPendingRemoveWindowManager = null; } appContext.setOuterContext(activity); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback); } ... // 通過Instrumentation回呼Activity的onCreate方法 ctivity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } }這里深入來看一下onCreate什么時候被呼叫
/frameworks/base/core/java/android/app/Instrumentation.java/; public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); // 呼叫了activity的performCreate方法 activity.performCreate(icicle, persistentState); postPerformCreate(activity); } /frameworks/base/core/java/android/app/Activity.java/; final void performCreate(Bundle icicle, PersistableBundle persistentState) { mCanEnterPictureInPicture = true; restoreHasCurrentPermissionRequest(icicle); // 這里就回呼了onCreate方法了 if (persistentState != null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } ... } -
Instrumentation通過類加載器來創建activity實體
/frameworks/base/core/java/android/app/Instrumentation.java/; public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { String pkg = intent != null && intent.getComponent() != null ? intent.getComponent().getPackageName() : null; // 利用AppComponentFactory進行實體化 return getFactory(pkg).instantiateActivity(cl, className, intent); } -
最后一步,通過AppComponentFactory工廠來創建實體,
/frameworks/support/compat/src/main/java/androidx/core/app/AppComponentFactory.java //其實就相當于直接回傳instantiateActivityCompat public final Activity instantiateActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return checkCompatWrapper(instantiateActivityCompat(cl, className, intent)); } //泛型方法 static <T> T checkCompatWrapper(T obj) { if (obj instanceof CompatWrapped) { T wrapper = (T) ((CompatWrapped) obj).getWrapper(); if (wrapper != null) { return wrapper; } } return obj; } //終于到了盡頭了,利用類加載器來進行實體化,到此activity的啟動就告一段落了, public @NonNull Activity instantiateActivityCompat(@NonNull ClassLoader cl, @NonNull String className, @Nullable Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { try { return (Activity) cl.loadClass(className).getDeclaredConstructor().newInstance(); } catch (InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException("Couldn't call constructor", e); } }
小結
上文通過整體流程和代碼詳解決議了一個activity啟動時的整體流程,不知道讀者們會不會有個疑問:了解這些有什么用呢?日常又用不到,當走完這整個流程的時候,你會發現你對于android又深入了解了很多了,面對開發的時候,內心也會更加有自信心,出現的一些bug,可能別人要解決好久,而你,很快就可以解決,另外,這一部分內容在插件化也有很大的使用,也是學習插件化必學的知識,
好了講了這么多,希望以上對你有幫助,有疑問可以評論區或者私信交流一下,另外,博主屬于android新手,如有不對之處還望指正,
參考文獻
- 《Android進階解密》
- 《Android開發藝術探索》
- Android進階(四):Activity啟動程序(最詳細&最簡單)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/233878.html
標籤:Android
