activity啟動過程的調(diào)用鏈那么長胃榕,很多源碼分析文章都是一個方法一個類地寫這個鏈,容易忘記,那么這個啟動過程中主要做了哪些重要的事?這才是重點
- 開啟一個新的Activity任務(wù)棧
Android M 6.0,關(guān)于ActivityThread和ApplicationThread的解析
問題:
1.ApplicationThread在用戶進程和在AMS進程分別是以什么形式出現(xiàn)挫剑?
2.它是如何作為用戶進程的服務(wù)端的?
3.Activity的context對象是在何時被賦值的柱衔?
在這個圖中樊破,ActivityManagerService和ActivityStack位于同一個進程中,而ApplicationThread和ActivityThread位于另一個進程中秀存。其中捶码,ActivityManagerService是負責(zé)管理Activity的生命周期的,ActivityManagerService還借助ActivityStack是來把所有的Activity按照后進先出的順序放在一個堆棧中或链;對于每一個應(yīng)用程序來說,都有一個ActivityThread來表示應(yīng)用程序的主進程档押,而每一個ActivityThread都包含有一個ApplicationThread實例澳盐,它是一個Binder對象祈纯,負責(zé)和其它進程進行通信。
簡要介紹一下啟動的過程:
Step 1. 無論是通過
Launcher
來啟動Activity
叼耙,還是通過Activity
內(nèi)部調(diào)用startActivity
接口來啟動新的Activity
腕窥,都通過Binder
進程間通信進入到ActivityManagerService
進程中,并且調(diào)用ActivityManagerService.startActivity
接口筛婉;Step 2. ActivityManagerService調(diào)用ActivityStack.startActivityMayWait來做準(zhǔn)備要啟動的Activity的相關(guān)信息簇爆;
Step 3. ActivityStack通知ApplicationThread要進行Activity啟動調(diào)度了,這里的ApplicationThread代表的是調(diào)用ActivityManagerService.startActivity接口的進程爽撒,對于通過點擊應(yīng)用程序圖標(biāo)的情景來說入蛆,這個進程就是Launcher了,而對于通過在Activity內(nèi)部調(diào)用startActivity的情景來說硕勿,這個進程就是這個Activity所在的進程了哨毁;
Step 4. ApplicationThread不執(zhí)行真正的啟動操作,它通過調(diào)用ActivityManagerService.activityPaused接口進入到ActivityManagerService進程中源武,看看是否需要創(chuàng)建新的進程來啟動Activity扼褪;
Step 5. 對于通過點擊應(yīng)用程序圖標(biāo)來啟動Activity的情景來說,ActivityManagerService在這一步中粱栖,會調(diào)用startProcessLocked來創(chuàng)建一個新的進程话浇,而對于通過在Activity內(nèi)部調(diào)用startActivity來啟動新的Activity來說,這一步是不需要執(zhí)行的闹究,因為新的Activity就在原來的Activity所在的進程中進行啟動凳枝;
Step 6. ActivityManagerServic調(diào)用ApplicationThread.scheduleLaunchActivity接口,通知相應(yīng)的進程執(zhí)行啟動Activity的操作跋核;
Step 7. ApplicationThread把這個啟動Activity的操作轉(zhuǎn)發(fā)給ActivityThread岖瑰,ActivityThread通過ClassLoader導(dǎo)入相應(yīng)的Activity類,然后把它啟動起來砂代。
這樣蹋订,系統(tǒng)就完成了Activity的啟動。
根Activity的啟動過程:
當(dāng)點擊手機桌面App圖標(biāo)時刻伊,應(yīng)用程序的啟動流程開啟
從Launcher進程進入到AMS所在進程:
創(chuàng)建App進程
上圖中露戒,到ActivityStack調(diào)用ActivityStackSupervisor. startSpecificActivityLocked()方法時,系統(tǒng)已為我們點擊的應(yīng)用創(chuàng)建了一個進程捶箱。
圖片來自劉望舒的CSDN博客
activity的Context賦值:
frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);//1
...
}
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);
...
}
return activity;
}
而這整個過程中所涉及到的進程通信:
圖片來自大神gityuan