閱讀本文大約需要花費50分鐘。
文章的內容主要還是從源碼進行分析,雖然又臭又長,但是如果想要學習Android系統源碼,這是必要走的路,沒有捷徑。
相對於碎片學習,我更傾向於靜下心來花費1個小時認真的學習一段內容。
專注於Android系統級源碼分析,Android的平臺設計,歡迎關注我,謝謝!
上一節我們講完了Android10.0的ActivityManagerService的啟動流程,在AMS的最後啟動了Launcher進程,今天我們就來看看Launcher的真正啟動流程。
系列文章:
1.概述
上一節我們學習了AMS\\ATM的啟動流程,這一節主要來學習Launcher的啟動流程。
在Android的中,桌面應用Launcher由Launcher演變到Launcher2,再到現在的Launcher3,Google也做了很多改動。
Launcher不支持桌面小工具動畫效果,Launcher2添加了動畫效果和3D初步效果支持,從Android 4.4 (KK)開始Launcher默認使用Launcher3, Launcher3加入了透明狀態欄,增加overview模式,可以調整workspace上頁面的前後順序,可以動態管理屏幕數量,widget列表與app list分開顯示等功能。
我們主要研究Launcher3的啟動過程。
2.核心源碼
從上面的代碼路徑可以看出,Android10.0中 Activity的相關功能被放到了wm的目錄中,在Android9.0中是在am目錄中,Google 最終的目的是把activity 和window融合,在Android10中只是做了簡單的代碼路徑的變更,正在的功能還要到後面的版本才能慢慢融合。
主要代碼作用:
- Instrumentation:
負責調用Activity和Application生命週期。
- ActivityTaskManagerService:
負責Activity管理和調度等工作。
ATM是Android10中新增內容
- ActivityManagerService:
負責管理四大組件和進程,包括生命週期和狀態切換。
- ActivityTaskManagerInternal:是由ActivityTaskManagerService對外提供的一個抽象類,真正的實現是在 ActivityTaskManagerService#LocalService
- ActivityThread:
管理應用程序進程中主線程的執行
- ActivityStackSupervisor:
負責所有Activity棧的管理
- TransactionExecutor:
主要作用是執行ClientTransaction
- ClientLifecycleManager:
生命週期的管理調用
3.架構
Android啟動流程圖:
Launcher啟動序列圖:
內容較多,例如Zygote的fork流程,realStartActivityLocked啟動Activity的中間過程,都沒有列出,下一個章節會單獨來講這部分內容.
4.源碼分析
上一節在AMS啟動過程中,我們知道了AMS啟動完成前,在systemReady()中會去調用startHomeOnAllDisplays()來啟動Launcher,本次就從startHomeOnAllDisplays()函數入口,來看看Launcher是如何被啟動起來的。
Launcher的啟動由三部分啟動:
- SystemServer完成啟動Launcher Activity的調用
- Zygote()進行Launcher進程的Fork操作
- 進入ActivityThread的main(),完成最終Launcher的onCreate操作
接下來我們分別從源碼部分來分析這三個啟動過程。
4.1第一階段SystemServer 啟動HomeActivity的調用階段
調用棧:
[ActivityTaskManagerService.java]
startHomeOnAllDisplays()
說明:
ActivityTaskManagerInternal是
ActivityTaskManagerService的一個抽象類,正在的實現是在ActivityTaskManagerService的LocalService,所以
mAtmInternal.startHomeOnAllDisplays()最終調用的是
ActivityTaskManagerService的
startHomeOnAllDisplays()方法
源碼:
4.2 [RootActivityContainer.java]
startHomeOnDisplay()
說明:在[4.1]中,獲取的displayId為DEFAULT_DISPLAY, 首先通過getHomeIntent 來構建一個category為CATEGORY_HOME的Intent,表明是Home Activity;
然後通過resolveHomeActivity()從系統所用已安裝的引用中,找到一個符合HomeItent的Activity,最終調用startHomeActivity()來啟動Activity
源碼:
4.2.1 [ActivityTaskManagerService.java]
getHomeIntent()
說明:構建一個category為CATEGORY_HOME的Intent,表明是Home Activity。
Intent.CATEGORY_HOME = "android.intent.category.HOME"
這個category會在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity
源碼:
4.2.2 [RootActivityContainer.java]
resolveHomeActivity()
說明:通過Binder跨進程通知PackageManagerService從系統所用已安裝的引用中,找到一個符合HomeItent的Activity
源碼:
4.3 [ActivityStartController.java ]
startHomeActivity()
說明:正在的啟動Home Activity入口。
obtainStarter() 方法返回的是 ActivityStarter 對象,它負責 Activity 的啟動,一系列 setXXX() 方法傳入啟動所需的各種參數,最後的 execute() 是真正的啟動邏輯。
另外如果home activity處於頂層的resume activity中,則Home Activity 將被初始化,但不會被恢復
並將保持這種狀態,直到有東西再次觸發它。我們需要進行另一次恢復。
源碼:
4.3.1 [ActivityStarter.java] execute()
說明:在[4.3]中obtainStarter沒有調用setMayWait的方法,因此mRequest.mayWait為false,走startActivity流程
源碼:
4.3.2 [ActivityStarter.java] startActivity()
說明:延時佈局,然後通過startActivityUnchecked()來處理啟動標記 flag ,要啟動的任務棧等,最後恢復佈局
源碼:
4.3.3 [RootActivityContainer.java]
resumeFocusedStacksTopActivities()
說明:獲取棧頂的Activity,恢復它
源碼:
4.3.4 [ActivityStackSupervisor.java]
startSpecificActivityLocked()
說明: 發佈消息以啟動進程,以避免在ATM鎖保持的情況下調用AMS時可能出現死鎖,最終調用到ATM的startProcess()
源碼:
4.3.5 [ActivityManagerService.java]
startProcess()
說明: 一路調用Process start(),最終到ZygoteProcess的
attemptUsapSendArgsAndGetResult(),用來fork一個新的Launcher的進程
源碼:
調用棧如下:
4.3.6 [ZygoteProcess.java]
attemptZygoteSendArgsAndGetResult()
說明:通過Socket連接Zygote進程,把之前組裝的msg發給Zygote,其中processClass ="android.app.ActivityThread",通過Zygote進程來Fork出一個新的進程,並執行 "android.app.ActivityThread"的main方法
源碼:
4.4 第二階段Zygote fork一個Launcher進程的階段
說明:Zygote的啟動過程我們前面有詳細講到過。
SystemServer的AMS服務向啟動Home Activity發起一個fork請求,Zygote進程通過Linux的fork函數,孵化出一個新的進程。
由於Zygote進程在啟動時會創建Java虛擬機,因此通過fork而創建的Launcher程序進程可以在內部獲取一個Java虛擬機的實例拷貝。
fork採用copy-on-write機制,有些類如果不做改變,甚至都不用複製,子進程可以和父進程共享這部分數據,從而省去不少內存的佔用。
fork過程,參考下圖:
Zygote的調用棧如下:
4.4.1 [ZygoteInit.java] main()
說明:Zygote先fork出SystemServer進程,接著進入循環等待,用來接收Socket發來的消息,用來fork出其他應用進程,比如Launcher
源碼:
4.4.2 [ZygoteConnection.java]
processOneCommand()
說明:通過forkAndSpecialize()來fork出Launcher的子進程,並執行handleChildProc,進入子進程的處理
源碼:
4.4.3 [ZygoteConnection.java]
handleChildProc()
說明:進行子進程的操作,最終獲得需要執行的ActivityThread的main()
源碼:
zygoteInit 進行一些環境的初始化、啟動Binder進程等操作:
把之前傳來的"android.app.ActivityThread" 傳遞給findStaticMain:
通過反射,拿到ActivityThread的main()方法:
把反射得來的ActivityThread main()入口返回給ZygoteInit的main,通過caller.run()進行調用:
4.5 第三個階段,Launcher在自己的進程中進行onCreate等後面的動作
從[4.4]可以看到,Zygote fork出了Launcher的進程,並把接下來的Launcher啟動任務交給了ActivityThread來進行,接下來我們就從ActivityThread main()來分析Launcher的創建過程。
調用棧如下:
4.5.1 [ActivityThread.java] main()
說明:主線程處理, 創建ActivityThread對象,調用attach進行處理,最終進入Looper循環
源碼:
調用ActivityThread的attach進行處理
4.5.2 [ActivityManagerService.java]
attachApplication()
說明:清除一些無用的記錄,最終調用ActivityStackSupervisor.java的 realStartActivityLocked(),進行Activity的啟動
源碼:
4.5.3 [ActivityStackSupervisor.java]
realStartActivityLocked()
說明:真正準備去啟動Activity,通過clientTransaction.addCallback把LaunchActivityItem的obtain作為回調參數加進去,再調用
ClientLifecycleManager.scheduleTransaction()得到
LaunchActivityItem的execute()方法進行最終的執行
參考上面的第三階段的調用棧流程
調用棧如下:
源碼:
4.5.4 [TransactionExecutor.java] execute()
說明:執行之前realStartActivityLocked()中的
clientTransaction.addCallback
調用棧如下圖所示:
源碼:
4.5.5 [ActivityThread.java]
handleLaunchActivity()
說明:主要乾了兩件事,第一件:初始化WindowManagerGlobal;第二件:調用performLaunchActivity方法
源碼:
4.5.6 [ActivityThread.java]
performLaunchActivity()
說明:獲取ComponentName、Context,反射創建Activity,設置Activity的一些內容,比如主題等;
最終調用callActivityOnCreate()來執行Activity的onCreate()方法
源碼:
callActivityOnCreate先執行activity onCreate的預處理,再去調用Activity的onCreate,最終完成Create創建後的內容處理
performCreate()主要調用Activity的onCreate()
至此,看到了我們最熟悉的Activity的onCreate(),Launcher的啟動完成,Launcher被真正創建起來。
5.總結
看到onCreate()後,進入到我們最熟悉的Activity的入口,Launcher的啟動告一段落。整個Android的啟動流程,我們也完整的分析完成。
Launcher的啟動經過了三個階段:
第一個階段:SystemServer完成啟動Launcher Activity的調用
第二個階段:Zygote()進行Launcher進程的Fork操作
第三個階段:進入ActivityThread的main(),完成最終Launcher的onCreate操作
下一節會來分析一下Android的進程創建過程以及Zygote的fork流程。
閱讀更多 IngresGe 的文章