Android10.0系統啟動之Launcher啟動流程-「Android取經之路」


Android10.0系統啟動之Launcher啟動流程-「Android取經之路」


閱讀本文大約需要花費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系統啟動之Launcher啟動流程-「Android取經之路」

從上面的代碼路徑可以看出,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啟動流程圖:


Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

Launcher啟動序列圖:

內容較多,例如Zygote的fork流程,realStartActivityLocked啟動Activity的中間過程,都沒有列出,下一個章節會單獨來講這部分內容.

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

Launcher啟動序列圖

4.源碼分析

上一節在AMS啟動過程中,我們知道了AMS啟動完成前,在systemReady()中會去調用startHomeOnAllDisplays()來啟動Launcher,本次就從startHomeOnAllDisplays()函數入口,來看看Launcher是如何被啟動起來的。


Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

Launcher的啟動由三部分啟動:

  1. SystemServer完成啟動Launcher Activity的調用
  2. Zygote()進行Launcher進程的Fork操作
  3. 進入ActivityThread的main(),完成最終Launcher的onCreate操作

接下來我們分別從源碼部分來分析這三個啟動過程。


4.1第一階段SystemServer 啟動HomeActivity的調用階段

調用棧:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

[ActivityTaskManagerService.java]

startHomeOnAllDisplays()

說明:

ActivityTaskManagerInternal是

ActivityTaskManagerService的一個抽象類,正在的實現是在ActivityTaskManagerService的LocalService,所以

mAtmInternal.startHomeOnAllDisplays()最終調用的是

ActivityTaskManagerService的

startHomeOnAllDisplays()方法

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.2 [RootActivityContainer.java]

startHomeOnDisplay()

說明:在[4.1]中,獲取的displayId為DEFAULT_DISPLAY, 首先通過getHomeIntent 來構建一個category為CATEGORY_HOME的Intent,表明是Home Activity;

然後通過resolveHomeActivity()從系統所用已安裝的引用中,找到一個符合HomeItent的Activity,最終調用startHomeActivity()來啟動Activity

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

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

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.2.2 [RootActivityContainer.java]

resolveHomeActivity()

說明:通過Binder跨進程通知PackageManagerService從系統所用已安裝的引用中,找到一個符合HomeItent的Activity

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.3 [ActivityStartController.java ]

startHomeActivity()

說明:正在的啟動Home Activity入口。

obtainStarter() 方法返回的是 ActivityStarter 對象,它負責 Activity 的啟動,一系列 setXXX() 方法傳入啟動所需的各種參數,最後的 execute() 是真正的啟動邏輯。

另外如果home activity處於頂層的resume activity中,則Home Activity 將被初始化,但不會被恢復

並將保持這種狀態,直到有東西再次觸發它。我們需要進行另一次恢復。

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.3.1 [ActivityStarter.java] execute()

說明:在[4.3]中obtainStarter沒有調用setMayWait的方法,因此mRequest.mayWait為false,走startActivity流程

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.3.2 [ActivityStarter.java] startActivity()

說明:延時佈局,然後通過startActivityUnchecked()來處理啟動標記 flag ,要啟動的任務棧等,最後恢復佈局

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.3.3 [RootActivityContainer.java]

resumeFocusedStacksTopActivities()

說明:獲取棧頂的Activity,恢復它

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.3.4 [ActivityStackSupervisor.java]

startSpecificActivityLocked()

說明:

發佈消息以啟動進程,以避免在ATM鎖保持的情況下調用AMS時可能出現死鎖,最終調用到ATM的startProcess()

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.3.5 [ActivityManagerService.java]

startProcess()

說明:

一路調用Process start(),最終到ZygoteProcess的

attemptUsapSendArgsAndGetResult(),用來fork一個新的Launcher的進程

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

調用棧如下:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.3.6 [ZygoteProcess.java]

attemptZygoteSendArgsAndGetResult()

說明:通過Socket連接Zygote進程,把之前組裝的msg發給Zygote,其中processClass ="android.app.ActivityThread",通過Zygote進程來Fork出一個新的進程,並執行 "android.app.ActivityThread"的main方法

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.4 第二階段Zygote fork一個Launcher進程的階段

說明:Zygote的啟動過程我們前面有詳細講到過。

SystemServer的AMS服務向啟動Home Activity發起一個fork請求,Zygote進程通過Linux的fork函數,孵化出一個新的進程。

由於Zygote進程在啟動時會創建Java虛擬機,因此通過fork而創建的Launcher程序進程可以在內部獲取一個Java虛擬機的實例拷貝。

fork採用copy-on-write機制,有些類如果不做改變,甚至都不用複製,子進程可以和父進程共享這部分數據,從而省去不少內存的佔用。

fork過程,參考下圖:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

Zygote的調用棧如下:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.4.1 [ZygoteInit.java] main()

說明:Zygote先fork出SystemServer進程,接著進入循環等待,用來接收Socket發來的消息,用來fork出其他應用進程,比如Launcher

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.4.2 [ZygoteConnection.java]

processOneCommand()

說明:通過forkAndSpecialize()來fork出Launcher的子進程,並執行handleChildProc,進入子進程的處理

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.4.3 [ZygoteConnection.java]

handleChildProc()

說明:進行子進程的操作,最終獲得需要執行的ActivityThread的main()

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

zygoteInit 進行一些環境的初始化、啟動Binder進程等操作:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

把之前傳來的"android.app.ActivityThread" 傳遞給findStaticMain:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

通過反射,拿到ActivityThread的main()方法:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

把反射得來的ActivityThread main()入口返回給ZygoteInit的main,通過caller.run()進行調用:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.5 第三個階段,Launcher在自己的進程中進行onCreate等後面的動作

從[4.4]可以看到,Zygote fork出了Launcher的進程,並把接下來的Launcher啟動任務交給了ActivityThread來進行,接下來我們就從ActivityThread main()來分析Launcher的創建過程。

調用棧如下:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.5.1 [ActivityThread.java] main()

說明:主線程處理, 創建ActivityThread對象,調用attach進行處理,最終進入Looper循環

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

調用ActivityThread的attach進行處理

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.5.2 [ActivityManagerService.java]

attachApplication()

說明:清除一些無用的記錄,最終調用ActivityStackSupervisor.java的 realStartActivityLocked(),進行Activity的啟動

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.5.3 [ActivityStackSupervisor.java]

realStartActivityLocked()

說明:真正準備去啟動Activity,通過clientTransaction.addCallback把LaunchActivityItem的obtain作為回調參數加進去,再調用

ClientLifecycleManager.scheduleTransaction()得到

LaunchActivityItem的execute()方法進行最終的執行

參考上面的第三階段的調用棧流程

調用棧如下:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.5.4 [TransactionExecutor.java] execute()

說明:執行之前realStartActivityLocked()中的

clientTransaction.addCallback

調用棧如下圖所示:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.5.5 [ActivityThread.java]

handleLaunchActivity()

說明:主要乾了兩件事,第一件:初始化WindowManagerGlobal;第二件:調用performLaunchActivity方法

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

4.5.6 [ActivityThread.java]

performLaunchActivity()

說明:獲取ComponentName、Context,反射創建Activity,設置Activity的一些內容,比如主題等;

最終調用callActivityOnCreate()來執行Activity的onCreate()方法

源碼:

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

callActivityOnCreate先執行activity onCreate的預處理,再去調用Activity的onCreate,最終完成Create創建後的內容處理

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

performCreate()主要調用Activity的onCreate()

Android10.0系統啟動之Launcher啟動流程-「Android取經之路」

至此,看到了我們最熟悉的Activity的onCreate(),Launcher的啟動完成,Launcher被真正創建起來。


5.總結

看到onCreate()後,進入到我們最熟悉的Activity的入口,Launcher的啟動告一段落。整個Android的啟動流程,我們也完整的分析完成。

Launcher的啟動經過了三個階段:

第一個階段:SystemServer完成啟動Launcher Activity的調用

第二個階段:Zygote()進行Launcher進程的Fork操作

第三個階段:進入ActivityThread的main(),完成最終Launcher的onCreate操作


下一節會來分析一下Android的進程創建過程以及Zygote的fork流程。



分享到:


相關文章: