Warning诀浪!本文基于API 29棋返,基于 API 30 的Activity啟動流程分析已更新,點擊:Activity啟動流程雷猪?基于Api30的Activity啟動流程分析 http://www.reibang.com/p/b68914037364
直接放圖睛竣。
第一次做這個圖的時候,我是按照api26的源碼來的春宣,然而現(xiàn)在已經(jīng)api29了……
Activity的啟動過程的源碼我看了多個版本的酵颁,每個版本都有一些變化,有些地方屬實搞得人摸不著頭腦月帝。尤其是中間這幾個類躏惋,一直在改動。比如這個ActivityStarter
嚷辅,如果我沒記錯的話是api23還是26才加進(jìn)來的簿姨;后來又把ActivityStackSupervisor
的一部分功能分離到了不同的類中◆じ悖看看源碼中的注釋:
好吧扁位,這個類即將被移除了……
個人感覺可能是Android團(tuán)隊前期埋的坑太多,留下了一些超巨型的類趁俊,很多類都超過了幾千上萬行域仇;然后隨著版本的更替,發(fā)現(xiàn)這么多功能都放一個類里面也不成寺擂,又在慢慢分離一些職責(zé)到其他類中暇务,所以就造成了一個版本一個樣泼掠,變化很快。代碼流程隨著版本優(yōu)化垦细,這也是必然的趨勢择镇。
不過呢,總體來講括改,大體的流程框架基本是固定的腻豌,太細(xì)節(jié)的地方也不需要過多糾結(jié)了。
言歸正傳嘱能,從頂至下吝梅,我個人把Activity的啟動流程依次分為三個階段:
App進(jìn)程中 ——(通過Binder)—→ 系統(tǒng)進(jìn)程中 ——(通過Binder)—→ 回到App進(jìn)程中
下面依次進(jìn)行梳理。(只保留關(guān)鍵代碼)
1. App進(jìn)程中
App進(jìn)程第一輪做的事兒不多惹骂,主要就是把傳進(jìn)來的Intent扔給AMS憔涉。
1.1 Activity
在Activity中調(diào)用了startActivity
方法后,不管調(diào)用的是哪個重載析苫,最后都會進(jìn)入到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);
……
}
然后就進(jìn)入到了Instrumentation.execStartActivity
方法中。
1.2 Instrumentation
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);
……
}
注意衩侥!重點国旷!
在之前的版本中,Instrumentation
都是通過Binder的方式調(diào)用AMS的方法啟動Activity的茫死;但是在api29中跪但,IPC的對象變成了ActivityTaskManagerService(ATMS)。根據(jù)這個類的說明峦萎,“此類提供有關(guān)Activity及其容器(如task屡久,stack和display)的信息,并與之交互爱榔。”網(wǎng)上關(guān)于這個類的信息不多被环,但是通過源碼可以發(fā)現(xiàn),這個類實際上就是AMS分離出的一部分職責(zé)(畢竟AMS兩萬多行详幽,也該瘦瘦身了)筛欢。
Instrumentation.execStartActivity
通過ActivityTaskManager.getService()
獲得了一個IActivityTaskManager
類型的對象,這是一個Binder對象唇聘,負(fù)責(zé)應(yīng)用和ATMS之間的通信版姑。也就是在這里,流程進(jìn)入到了第二階段:系統(tǒng)進(jìn)程中迟郎。
2. 系統(tǒng)進(jìn)程中
2.1 ATMS(ActivityTaskManagerService)
ATMS運行在系統(tǒng)服務(wù)進(jìn)程(system_server)之中剥险。當(dāng)App通過Instrumentation和ATMS跨進(jìn)程通信之后,ATMS就代管了接下來的啟動流程宪肖。
ATMS在進(jìn)行了簡單處理之后表制,就會交給ActivityStarter
處理宇姚。(這其實跟之前的AMS一模一樣)
public final int startActivity(...args) {
return startActivityAsUser(...args);
}
public final int startActivityAsUser(args) {
// ...
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.......
.execute();
}
上述代碼中,getActivityStartController().obtainStarter
會返回一個ActivityStarter
對象夫凸。(這個ActivityStartController
中有一個ActivityStarter.DefaultFactory
類型的成員變量,它維護(hù)了一個ActivityStarter池阱持。obtainStarter()
就是從里面取的夭拌。)
然后ActivityStarter.execute()
會根據(jù)傳入的字符串"startActivityAsUser"
來進(jìn)行接下來的流程。
2.2 一些重要的類
接下來的工作衷咽,就是一系列的類協(xié)同處理了鸽扁。代碼非常復(fù)雜,但是看個大概流程還是不難的镶骗,畢竟Android源代碼近億行桶现,不可能全部都仔細(xì)讀完。
這部分主要涉及了幾個類:ActivityStarter
鼎姊、ActivityStackSupervisor
骡和、ActivityRecord
、TaskRecord
相寇、ActivityStack
慰于。
ActivityStarter
顧名思義,ActivityStarter
是用來啟動Activity的唤衫,同時也在其中判斷了啟動模式的邏輯婆赠;
ActivityStackSupervisor
顧名思義,ActivityStackSupervisor
則是ActivityStack的管理者佳励。
ActivityRecord
而每次啟動一個Activity休里,都有一個對應(yīng)的ActivityRecord
被記錄下來。這個ActivityRecord是在ActivityStarter.startActivity(IApplicationThread, ...)
方法中被創(chuàng)建的赃承,也就是在這里妙黍,Activity的啟動信息完成了從intent到ActivityRecord的蛻變。ActivityRecord
包含了一個Activity的所有信息瞧剖,可以看做是Activity的“身份證”废境。
TaskRecord
任務(wù)。一個TaskRecord
就是在四種啟動模式中所說的“椡卜保”噩凹。一個TaskRecord
,或者說一個Task毡咏、任務(wù)驮宴,根據(jù)官方說法,任務(wù)是用戶在執(zhí)行某項工作時與之互動的一系列 Activity 的集合呕缭。也就是說堵泽,一個任務(wù)是包含了若干個Activity的修己。對于啟動模式為singleInstance的Activity來說,會單獨存在于一個棧中迎罗,也就是這個任務(wù)中只有一個Activity睬愤;而其他啟動模式的Activity則會在當(dāng)前棧中進(jìn)行。具體的參考官網(wǎng)定義啟動模式纹安。
ActivityStack
ActivityStack顧名思義尤辱,也就是Activity棧。通常來講厢岂,一個系統(tǒng)里面有兩個ActivityStack光督,一個是系統(tǒng)Launcher所在的ActivityStack,一個是用戶App運行的ActivityStack塔粒。通常App所在的棧就是后者结借。
一個ActivityStack
包含了多個TaskRecord
,如圖所示:圖片來源
2.3 ActivityStarter
顧名思義卒茬,ActivityStarter肩負(fù)著Activity啟動的職責(zé)船老。之前說到,ATMS調(diào)用了ActivityStarter.execute()
方法圃酵,execute()
又會調(diào)用startActivityMayWait()
方法努隙。
startActivityMayWait
為什么這個方法名字里有個“MayWait”呢?因為接下來的流程都是在同步代碼塊里面進(jìn)行的辜昵,保證了Activity的啟動在多線程下的安全性荸镊。這個方法會做一系列的驗證和處理,比如根據(jù)Intent來從PackageManagerService收集待啟動Activity的信息(AndroidManifest中的信息)堪置。
startActivity
startActivityMayWait
最終會調(diào)用startActivity
躬存。startActivity
共有三個重載,關(guān)鍵是在這個流程里面舀锨,這三個重載挨個都被調(diào)用了……不得不吐槽岭洲,Android這個方法名字取得真的毫無特色,不仔細(xì)看根本不知道他是干啥的坎匿;這三步我就合到一起寫了盾剩。過程很冗長,大多是做一些條件的判斷替蔬,以及繼續(xù)收集目標(biāo)Activity的信息告私。最重要的是,在這個過程中承桥,根據(jù)收集到的這些信息驻粟,目標(biāo)Activity對應(yīng)的ActivityRecord
終于被創(chuàng)建了。
startActivityUnchecked
經(jīng)過三個startActivity
方法之后凶异,終于到了重頭戲了蜀撑。在startActivityUnchecked
方法中挤巡,包含了關(guān)于啟動模式launchMode的邏輯。根據(jù)任務(wù)棧中是否已經(jīng)存在該Activity實例酷麦、AndroidManifest中設(shè)置的啟動模式和傳入Intent中的flags等矿卑,判斷出目標(biāo)Activity的啟動方式(《定義啟動模式》有詳盡的關(guān)于啟動模式的說明)。
在判斷完Activity的啟動方式之后沃饶,startActivityUnchecked
方法中有這么一句代碼:
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions);
看到這個方法名母廷,我以為流程就走這繼續(xù)了呢;結(jié)果點進(jìn)去看了半天才發(fā)現(xiàn)绍坝,這個方法處理的是把目標(biāo)Activity壓入相應(yīng)的任務(wù)棧(或者新建任務(wù)棧或者pop上方Activity苔悦,諸如此類)相關(guān)的邏輯轩褐,另外就是創(chuàng)建Starting Window相關(guān)的邏輯;這算是個支線任務(wù)玖详。真正啟動Activity的流程還得往下看把介。
后面的邏輯就很清晰了,刪去旁支之后:
if (mDoResume) {
// ...
mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);
}
不過這個mDoResume又是哪兒來的蟋座?經(jīng)過我的不懈努力拗踢,終于在某個startActivity
方法中發(fā)現(xiàn)了,其實他就是true:
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
OK向臀,到這就很明了了巢墅。所以說,到這又跟之前版本不同了券膀,沒有經(jīng)過ActivityStackSupervisor
君纫,而是調(diào)用了RootActivityContainer.resumeFocusedStacksTopActivities
。
2.4 RootActivityContainer / ActivityStack / ActivityStackSupervisor
這個RootActivityContainer
又是何方神圣呢芹彬?看看它的注釋:
Root node for activity containers. TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
意思就是蓄髓,這是個臨時類,分離了一部分
ActivityStackSupervisor
的職責(zé)舒帮,到最后這個類會被合并到RootWindowContainer
類中会喝;之前這一步的確應(yīng)該是交給ActivityStackSupervisor
的。根據(jù)源碼中的注釋所言玩郊,之后ActivityStackSupervisor
類會被徹底消滅掉肢执,類的職責(zé)會被其他類分割。
總而言之译红,這個類暫時就是ActivityStackSupervisor
一部分的替代品蔚万,之后這部分工作就應(yīng)該是RootWindowContainer
來做了。
RootActivityContainer.resumeFocusedStacksTopActivities()及之后的一系列方法
回到RootActivityContainer.resumeFocusedStacksTopActivities
方法中临庇;這開始之后的調(diào)用鏈依次是:
RootActivityContainer.resumeFocusedStacksTopActivities
-> ActivityStack.resumeTopActivityUncheckedLocked
-> ActivityStack.resumeTopActivityInnerLocked
它們的共同作用就是確保剛才壓入棧的目標(biāo)Activity能夠順利resume反璃,包括各種狀態(tài)的判斷昵慌、暫停當(dāng)前Activity、處理過渡動畫等淮蜈。而在ActivityStack.resumeTopActivityInnerLocked
方法的最后:
if (next.attachedToProcess()) {
// ...
} else {
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
這個attachedToProcess
方法的返回值也折騰了我很久斋攀;最后終于發(fā)現(xiàn),只有啟動了的Activity才會返回true梧田。所以代碼最終進(jìn)入到了ActivityStackSupervisor.startSpecificActivityLocked
方法中淳蔼。此時第二階段的流程已經(jīng)接近尾聲。
ActivityStackSupervisor.startSpecificActivityLocked()
中又調(diào)用了
ActivityStackSupervisor.realStartActivityLocked()
終于裁眯,看到這個名字就知道鹉梨,這是真正的啟動Activity了!
ActivityStackSupervisor.realStartActivityLocked(ActivityRecord, WindowProcessController, boolean, boolean)
這個方法有200多行穿稳,但是最關(guān)鍵的其實就是下面這一段:
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
這里的mService是ATMS存皂,它通過LifecycleManager
傳遞了一個Activity啟動的事務(wù);scheduleTransaction
是這樣的:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
// ...
}
撥云見日逢艘!熟悉的IApplicationThread
旦袋,終于結(jié)束了在系統(tǒng)進(jìn)程中的流程,又要回到App進(jìn)程了它改。
3. 重回App進(jìn)程
繼續(xù)偷圖疤孕,原文http://www.reibang.com/p/42cc38ba6112
參考資料
http://www.reibang.com/p/42cc38ba6112
http://www.reibang.com/p/94816e52cd77
https://developer.android.google.cn/guide/components/activities/tasks-and-back-stack