一、Activity啟動流程(基于API30)
這里把Activity 啟動流程分為三個階段
App進程中----(通過binder)---->系統(tǒng)進程中----(通過Binder)----->回到App進程汤求。
最起碼要熟悉 “App進程中” 和 “回到App進程” 的部分躲胳。
下面依次進行梳理潘拱。(只保留關鍵部分)
1. App進程中
1.1 ContextImp startActivity()/Activity startActivity()
這里需要簡單說明一下贪磺,對于開發(fā)者來說拱撵,在代碼中主動啟動activity 的入口有兩重辉川,一個是Activity 的startActivity()系列方法(startActivityForResult 也是可以直接調(diào)用的),一個是其他Context的startActivity()方法拴测,其他Context的startActivity()方法最終實現(xiàn)在ContextImp類內(nèi)乓旗。兩個入口都調(diào)用到了Instrumentation 的execStartActivity()方法。
ContextImpl的startActivity 方法如下集索,可以看到最后會進入到了Instrumentation.execStartActivity方法中屿愚,這個和Activity startActivity()方法是一樣的,后面的分析可以看到务荆。這里還需要注意的是妆距,調(diào)用Instrumentation.execStartActivity方法前有對Intent進行判斷,從主動拋出的異常信息描述可以看出函匕,對Intent 的 flags 是有要求的娱据,一般我們都是給Intent 添加Intent.FLAG_ACTIVITY_NEW_TASK 。這里也是跟調(diào)用Activity 的 startActivity 不一樣的地方盅惜。
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
final int targetSdkVersion = getApplicationInfo().targetSdkVersion;
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& (targetSdkVersion < Build.VERSION_CODES.N
|| targetSdkVersion >= Build.VERSION_CODES.P)
&& (options == null
|| ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
在Activity中調(diào)用了startActivity方法后中剩,不管調(diào)用的是哪個重載忌穿,最后都會進入到startActivityForResult(Intent, int, Bundle)中。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
……
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
……
}
然后就進入到了Instrumentation.execStartActivity方法中结啼。
1.2 Instrumentation execStartActivity()
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
……
ActivityTaskManager.getService().startActivity(
whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
……
}
在這里掠剑,通過ActivityTaskManager.getService()獲取到一個IActivityTaskManager對象。通過其獲取方式:
// ActivityTaskManager類
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
可以看到郊愧,這是一個Binder對象澡腾,用于跨進程調(diào)用系統(tǒng)服務。
注意糕珊!重點动分!
在之前的版本中,Instrumentation都是通過Binder的方式調(diào)用AMS的方法啟動Activity的红选;但是在api29之后澜公,IPC的對象變成了ActivityTaskManagerService(ATMS)。
2. 系統(tǒng)進程中
2.1 ATMS(ActivityTaskManagerService)
ATMS運行在系統(tǒng)服務進程(system_server)之中喇肋。當App通過Instrumentation和ATMS跨進程通信之后坟乾,ATMS就代管了接下來的啟動流程。
ATMS在進行了簡單處理之后蝶防,就會交給ActivityStarter處理甚侣。
public final int startActivity(...args) {
return startActivityAsUser(...args);
}
public final int startActivityAsUser(args) {
// ...
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.......
.execute();
}
2.2 一些重要的類
接下來的工作,就是一系列的類協(xié)同處理了间学。代碼非常復雜殷费,但是看個大概流程還是不難的,畢竟Android源代碼近億行低葫,不可能全部都仔細讀完详羡。
這部分主要涉及了幾個類:ActivityStarter
、ActivityStackSupervisor
嘿悬、ActivityRecord
实柠、TaskRecord
、ActivityStack
善涨。
ActivityStarter
顧名思義窒盐,ActivityStarter
是用來啟動Activity的,同時也在其中判斷了啟動模式的邏輯钢拧;
ActivityStackSupervisor
顧名思義蟹漓,ActivityStackSupervisor
則是ActivityStack的管理者。
ActivityRecord
而每次啟動一個Activity娶靡,都有一個對應的ActivityRecord
被記錄下來牧牢。這個ActivityRecord是在ActivityStarter.startActivity(IApplicationThread, ...)
方法中被創(chuàng)建的,也就是在這里姿锭,Activity的啟動信息完成了從intent到ActivityRecord的蛻變塔鳍。ActivityRecord
包含了一個Activity的所有信息,可以看做是Activity的“身份證”呻此。
TaskRecord
任務轮纫。一個TaskRecord
就是在四種啟動模式中所說的“棧”焚鲜。一個TaskRecord
掌唾,或者說一個Task、任務忿磅,根據(jù)官方說法糯彬,任務是用戶在執(zhí)行某項工作時與之互動的一系列 Activity 的集合。也就是說葱她,一個任務是包含了若干個Activity的撩扒。對于啟動模式為singleInstance的Activity來說,會單獨存在于一個棧中吨些,也就是這個任務中只有一個Activity搓谆;而其他啟動模式的Activity則會在當前棧中進行。具體的參考官網(wǎng)定義啟動模式豪墅。
ActivityStack
ActivityStack顧名思義泉手,也就是Activity棧。通常來講偶器,一個系統(tǒng)里面有兩個ActivityStack斩萌,一個是系統(tǒng)Launcher所在的ActivityStack,一個是用戶App運行的ActivityStack屏轰。通常App所在的棧就是后者术裸。
系統(tǒng)進程中的過程請看
https://blog.csdn.net/zengsidou/article/details/117177399
3.回到App進程
3.1. ApplicationThread / ActivityThread
ApplicationThread是ActivityThread的內(nèi)部類,繼承自IApplicationThread.Stub亭枷,是一個Binder類袭艺,用于當前應用進程和系統(tǒng)進程之間的跨進程通信。
而ApplicationThread的scheduleTransaction方法其實是調(diào)用了ActivityThread的同名方法叨粘。而ActivityThread自身并沒有定義這個方法猾编,而是繼承自ClientTransactionHandler來的∩茫看下這個方法:
// ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
// ActivityThread
private void sendMessage(int what, Object obj) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
mH.sendMessage(msg);
}
所以scheduleTransaction方法其實就是給ActivityThread內(nèi)部HandlermH發(fā)送了一個值為ActivityThread.H.EXECUTE_TRANSACTION的消息答倡,并把事務傳遞了過去。
而mH的處理方式就是把這個事務交給mTransactionExecutor來執(zhí)行驴党。
3.2. TransactionExecutor
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
...
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);
}
}
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
...
cycleToPath(r, lifecycleItem.getTargetState(), true, transaction);
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
}
邏輯很簡單瘪撇,就是分別調(diào)用了這個事務Callback和LifecycleState的execute方法;另外就是調(diào)用了cycleToPath方法,這個方法用于生命周期的過渡倔既。
這里的在Callback和LifecycleState是在之前ActivityStackSupervisor的realStartActivityLocked方法中創(chuàng)建的恕曲,分別對應的是LaunchActivityItem和ResumeActivityItem這兩個類,即啟動和恢復Activity渤涌。
這里按照順序平鋪下來為:LaunchActivityItem.execute() -> cycleToPath() -> ResumeActivityItem.execute()佩谣。
看看這兩個類的execute方法和cycleToPath方法:
// LaunchActivityItem 的 execute 方法
public void execute(...args) {
client.handleLaunchActivity(...args);
}
// ResumeActivityItem 的 execute 方法
public void execute(...args) {
client.handleResumeActivity(...args);
}
// TransactionExecutor.cycleToPath
private void cycleToPath(...args) {
...
performLifecycleSequence(r, path, transaction);
}
private void performLifecycleSequence(...args) {
...
// 這里的state是ON_START
switch (state) {
...
case ON_START:
mTransactionHandler.handleStartActivity(r.token, mPendingActions);
}
}
而這里的client參數(shù)和mTransactionHandler是TransactionExecutor對象創(chuàng)建的時候就傳入的,實際上都是是對應應用進程的ActivityThread對象实蓬。
也就是說茸俭,到頭來最終還是分別調(diào)用了ActivityThread的handleLaunchActivity,handleStartActivity和handleResumeActivity方法安皱,分別對應了Activity的onCreate调鬓、onStart、onResume回調(diào)酌伊。
3.3. ActivityThread
handleLaunchActivity的核心是調(diào)用performLaunchActivity方法腾窝。performLaunchActivity大體上依次做了這些事:
通過反射創(chuàng)建Activity實例,這是通過Instrumentation.newActivity方法實現(xiàn)的腺晾;
- 通過Activity.attach方法燕锥,實例化Window對象;
- 通過Instrumentation調(diào)用Activity的onCreate回調(diào)悯蝉;
在handleStartActivity方法中:
- 主要是調(diào)用了對應Activity的performStart方法归形,其中調(diào)用了onStart回調(diào);
- 通過Instrumentation調(diào)用onRestoreInstanceState回調(diào)鼻由;
與handleLaunchActivity類似的暇榴,handleResumeActivity則是調(diào)用了
performResumeActivity方法。其大體上依次做了:
- 如果需要蕉世,調(diào)用待Resume Activity的onNewIntent蔼紧、onActivityResult回調(diào);
- 調(diào)用Activity的performResume方法狠轻,其中調(diào)用了onResume回調(diào)奸例;