整個 startActivity 的流程分為 3 大部分宣脉,也涉及 3 個進程之間的交互:
1. ActivityA --> ActivityManagerService(簡稱 AMS)
2. ActivityManagerService --> ApplicationThread
3. ApplicationThread --> Activity
1.ActivityA --> ActivityManagerService 階段
Activity 的 startActivity
最終調(diào)用到了startActivityForResult,傳入-1表示不需要獲取startActivity的結(jié)果。
Activity 的 startActivityForResult
1.Instrumentation 類主要用來監(jiān)控應用程序與系統(tǒng)交互民鼓。
2.mMainThread是ActivityThread,可以理解為一個進程润脸,初始啟動Activity所在的進程怔球。
3.通過 mMainThread 獲取一個 ApplicationThread 的引用,這個引用就是用來實現(xiàn)進程間通信的,具體來說就是 AMS 所在系統(tǒng)進程通知應用程序進程進行的一系列操作吴攒。
Instrumentation 的 execStartActivity
在 Instrumentation.execStartA ctivity方法中张抄,先通過 ActivityManger.getService 獲取 AMS 的實例,然后調(diào)用其 startActivity 方法洼怔,實際上這里就是通過 AIDL 來調(diào)用 AMS 的 startActivity 方法署惯,至此,startActivity 的工作重心成功地從進程 A 轉(zhuǎn)移到了系統(tǒng)進程 AMS 中镣隶。
2.ActivityManagerService --> ApplicationThread
AMS-->ApplicationThread 流程里面實際做了兩件事:
1.綜合處理 launchMode 和 Intent 中的 Flag 標志位极谊,并根據(jù)處理結(jié)果生成一個目標 Activity B 的對象(ActivityRecord)。
2.判斷是否需要為目標 Activity B 創(chuàng)建一個新的進程(ProcessRecord)安岂、新的任務棧(TaskRecord)轻猖。
AMS 的 startActivity
經(jīng)過多次調(diào)用,最終調(diào)用到startActivityAsUser方法中域那,通過obtainStarter方法獲取ActivityStarter 類型的對象咙边,然后調(diào)用其 execute 方法。在 execute 方法中次员,會再次調(diào)用其內(nèi)部的 startActivityMayWait 方法败许。
ActivityStarter 的 startActivityMayWait
1.通過ActivityStackSupervisor獲取ResolveInfo信息。resolveIntent 中實際上是調(diào)用系統(tǒng)PackageManagerService 來獲取最佳 Activity淑蔚。
有時候我們通過隱式 Intent 啟動 Activity 時市殷,系統(tǒng)中可能存在多個 Activity 可以處理 Intent,此時會彈出一個選擇框讓用戶選擇具體需要打開哪一個 Activity 界面刹衫,就是此處的邏輯處理結(jié)果醋寝。
2.通過ActivityStackSupervisor獲取ActivityInfo信息。
3.調(diào)用重載方法startActivity啟動Activity带迟。
從圖中可以看出獲取目標 Activity 信息的操作由 mSupervisor 來實現(xiàn)音羞,它是 ActivityStackSupervisor 類型,從名字也能猜出它主要是負責 Activity 所處棧的管理類仓犬。
startActivity 方法黄选,而最終會調(diào)用的 ActivityStarter 中的 startActivityUnchecked 方法來獲取啟動 Activity 的結(jié)果。
ActivityStarter 的 startActivityUnchecked
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
...
//計算啟動 Activity 的 Flag 值
computeLaunchingTaskFlags();
...
//處理 Task 和 Activity 的進棧操作
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,mOptions);
...
//啟動棧中頂部的 Activity
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);
...
}
computeLaunchingTaskFlags方法如下:
這個計算啟動Activity的Flag值婶肩,不同的 Flag 決定了啟動 Activity 最終會被放置到哪一個 Task 集合中办陷。
- mInTask 是 TaskRecord 類型,此處為 null律歼,代表 Activity 要加入的棧不存在民镜,因此需要判斷是否需要新建 Task。
- mSourceRecord 的類型 ActivityRecord 類型险毁,它是用來描述“初始 Activity”制圈, ActivityA 啟動了ActivityB们童,ActivityA 就是初始 Activity。當我們使用 Context 或者 Application 啟動 Activity 時鲸鹦, SourceRecord 為 null慧库。
- 表示初始 Activity 如果是在 SingleInstance 棧中的 Activity,這種需要添加 NEW_TASK 的標識馋嗜。SingleInstance 棧只能允許保存一個 Activity齐板。
- 如果 Launch Mode 設(shè)置了 singleTask 或 singleInstance,則也要創(chuàng)建一個新棧葛菇。
ActivityStack 的 startActivityLocked
調(diào)用 insertTaskAtTop 方法嘗試將 Task 和 Activity 入棧甘磨。如果 Activity 是以 newTask 的模式啟動或者 TASK 堆棧中不存在該 Task id,則 Task 會重新入棧眯停,并且放在棧的頂部济舆。需要注意的是:Task 先入棧,之后才是 Activity 入棧莺债,它們是包含關(guān)系滋觉。
一個ActivityRecord對應一個Activity,保存了一個Activity的所有信息; 但是一個Activity可能會有多個ActivityRecord,因為Activity可以被多次啟動齐邦,這個主要取決于其啟動模式椎侠。
一個TaskRecord由一個或者多個ActivityRecord組成,這就是我們常說的任務棧侄旬,具有后進先出的特點。
ActivityStack則是用來管理TaskRecord的煌妈,包含了多個TaskRecord儡羔。
參考Activity啟動流程
ActivityStackSupervisor的resumeFocusedStackTopActivityLocked
經(jīng)過一系列調(diào)用,最終代碼有回到了ActivityStackSupervisor 中的 startSpecificActivityLocked 方法璧诵。
ActivityStackSupervisor 的 startSpecificActivityLocked
1.根據(jù)進程名稱和 Application 的 uid 來判斷目標進程是否已經(jīng)創(chuàng)建汰蜘,如果沒有則代表進程未創(chuàng)建。
2.不管是目標進程已經(jīng)存在還是新建目標進程之宿,最終都會調(diào)用圖中紅線標記的 realStartActivityLocked 方法來執(zhí)行啟動 Activity 的操作族操。
3.調(diào)用 AMS 創(chuàng)建 Activity 所在進程。
ActivityStackSupervisor 的 realStartActivityLocked
- 處創(chuàng)建 Activity 啟動事務比被,并傳入 app.thread 參數(shù)色难,它是 ApplicationThread 類型。在上文 startActivity 階段已經(jīng)提過 ApplicationThread 是為了實現(xiàn)進程間通信的等缀,是 ActivityThread 的一個內(nèi)部類枷莉。
- 處執(zhí)行 Activity 啟動事務。
Activity 啟動事務的執(zhí)行是由 ClientLifecycleManager 來完成的尺迂。
ClientLifecycleManager.scheduleTransaction
可以看出實際上是調(diào)用了啟動事務 ClientTransaction 的 schedule 方法笤妙,而這個 transaction 實際上是在創(chuàng)建 ClientTransaction 時傳入的 app.thread 對象冒掌,也就是 ApplicationThread。
- 傳入的 app.thread 會賦值給 ClientTransaction 的成員變量 mClient蹲盘,ClientTransaction 會調(diào)用 mClient.scheduleTransaction(this) 來執(zhí)行事務股毫。
- app.thread 是 ActivityThread 的內(nèi)部類 ApplicationThread,所以事務最終是調(diào)用 app.thread 的 scheduleTransaction 執(zhí)行召衔。
- 到這為止 startActivity 操作就成功地從 AMS 轉(zhuǎn)移到了另一個進程 B 中的 **ApplicationThread **中铃诬,剩下的就是 AMS 通過進程間通信機制通知 ApplicationThread 執(zhí)行 ActivityB 的生命周期方法。
3.ApplicationThread -> Activity
剛才我們已近分析了 AMS 將啟動 Activity 的任務作為一個事務 ClientTransaction 去完成薄嫡,在 ClientLifecycleManager 中會調(diào)用 ClientTransaction的schedule() 方法氧急,如下:
mClient 是一個 IApplicationThread 接口類型,具體實現(xiàn)是 ActivityThread 的內(nèi)部類 ApplicationThread毫深。因此后續(xù)執(zhí)行 Activity 生命周期的過程都是由 ApplicationThread 指導完成的吩坝,scheduleTransaction 方法如下:
調(diào)用了ActivityThread 的 scheduleTransaction 方法。但是這個方法實際上是在 ActivityThread 的父類 ClientTransactionHandler 中實現(xiàn)哑蔫,具體如下:
調(diào)用 sendMessage 方法钉寝,向 Handler 中發(fā)送了一個 EXECUTE_TRANSACTION 的消息,并且 Message 中的 obj 就是啟動 Activity 的事務對象闸迷。而這個 Handler 的具體實現(xiàn)是 ActivityThread 中的 mH 對象嵌纲。具體如下:
public final class ActivityThread extends ClientTransactionHandler {
final H mH = new H();
class H extends Handler {
...
case EXECUTE_TRANSACTION:
return "EXECUTE_TRANSACTION";
...
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
...
}
}
}
最終調(diào)用了事務的 execute 方法,execute 方法如下:
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
public void executeCallbacks(ClientTransaction transaction) {
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
log("Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState);
}
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
}
if (postExecutionState != UNDEFINED && r != null) {
// Skip the very last transition and perform it by explicit state request instead.
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition);
}
}
}
在 executeCallback 方法中腥沽,會遍歷事務中的 callback 并執(zhí)行 execute 方法逮走,這些 callbacks 是何時被添加的呢?
在創(chuàng)建 ClientTransaction 時今阳,通過 addCallback 方法傳入了 Callback 參數(shù)师溅,從圖中可以看出其實是一個 LauncherActivityItem 類型的對象。
LaunchActivityItem 的 execute()
終于到了跟 Activity 生命周期相關(guān)的方法了盾舌,圖中 client 是 ClientTransationHandler 類型墓臭,實際實現(xiàn)類就是 ActivityThread。因此最終方法又回到了 ActivityThread妖谴。
ActivityThread 的 handleLaunchActivity
Activity 的生命周期方法就是在這個方法中有序執(zhí)行窿锉,具體如下:
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
//1
WindowManagerGlobal.initialize();
//2
final Activity a = performLaunchActivity(r, customIntent);
...
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
try {
//3
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
...
}
...
//4
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);
...
//5
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
- 初始化 Activity 的 WindowManager,每一個 Activity 都會對應一個“窗口膝舅。
- 調(diào)用 performLaunchActivity 創(chuàng)建并顯示 Activity嗡载。
- 通過反射創(chuàng)建目標 Activity 對象。
- 調(diào)用 attach 方法建立 Activity 與 Context 之間的聯(lián)系仍稀,創(chuàng)建 PhoneWindow 對象鼻疮,并與 Activity 進行關(guān)聯(lián)操作。
- 通過 Instrumentation 最終調(diào)用 Activity 的 onCreate 方法琳轿。
4.總結(jié)
Activity 的啟動過程主要涉及 3 個進程間的通信過程:
首先進程 A 通過 Binder 調(diào)用 AMS 的 startActivity 方法判沟。
然后 AMS 通過一系列的計算構(gòu)造目標 Intent耿芹,然后在 ActivityStack 與 ActivityStackSupervisor 中處理 Task 和 Activity 的入棧操作。
最后 AMS 通過 Binder 機制挪哄,調(diào)用目標進程中 ApplicationThread 的方法來創(chuàng)建并執(zhí)行 Activity 生命周期方法吧秕,實際上 ApplicationThread 是 ActivityThread 的一個內(nèi)部類,它的執(zhí)行最終都調(diào)用到了 ActivityThread 中的相應方法迹炼。