Android App 啟動(dòng)流程源碼分析

Blog - Android App 啟動(dòng)流程源碼分析

App 啟動(dòng)是多個(gè)進(jìn)程復(fù)雜交互的過(guò)程,本文主要分析從 Launcher 到 App 啟動(dòng)過(guò)程中,應(yīng)用層開發(fā)人員需要知道的大致流程。

流程總覽

流程概覽.png

名詞說(shuō)明

Launcher:桌面應(yīng)用進(jìn)程;
AMS:ActivityManagerService,位于系統(tǒng) system_server 進(jìn)程中;
App:要啟動(dòng)的 App 進(jìn)程。

大致流程

流程上大體可分為四步:

  1. Launcher 通知 AMS 啟動(dòng) App。
  2. AMS 通知 Launcher 休眠。
  3. AMS 啟動(dòng)目標(biāo) App 進(jìn)程。
  4. AMS 啟動(dòng)目標(biāo) App 的 Activity。

詳細(xì)步驟

下面將分析每一步驟在 Android 應(yīng)用程序進(jìn)程中所做的事。

步驟1:Launcher 通知 AMS 啟動(dòng) App

Launcher 通知 AMS 啟動(dòng) App.png

如圖,Launcher 的 Activity 的經(jīng)過(guò)層層調(diào)用,最終交給 AMS 去啟動(dòng)目標(biāo) App。

這里,IActivityManager 是應(yīng)用程序進(jìn)程與 SystemServer(AMS 所在進(jìn)程)通信的 Binder 在 Client 端的代理,因?yàn)槭菓?yīng)用程序進(jìn)程向 AMS 發(fā)消息,所以應(yīng)用程序進(jìn)程是 Client 端。

步驟2:AMS 通知 Launcher 休眠。

AMS 在收到 Launcher 請(qǐng)求之后,會(huì)去目標(biāo) App 的 AndroidManifest 中檢查 Activity 是否存在,不存在則拋出 ActivityNotFoundException。如果校驗(yàn)沒(méi)有問(wèn)題,則會(huì)將要啟動(dòng)的頁(yè)面保存起來(lái),然后通知 Launcher 休眠。

通知 Launcher 休眠也是 Binder 通信過(guò)程,由于這次是 AMS 向 Launcher 發(fā)消息,所以 AMS 是 Client 端。它的 Client 端類為 ApplicationThreadProxy,它將方法傳給 Server 端(應(yīng)用程序進(jìn)程)的 ApplicationThread。你搜索不到 ApplicationThread,因?yàn)樗?ActivityThread 的內(nèi)部類。

下面流程圖只分析 Launcher 休眠的過(guò)程,即在應(yīng)用程序進(jìn)程的具體執(zhí)行步驟,因?yàn)閷?duì)于應(yīng)用層開發(fā)人員來(lái)說(shuō)這些方法調(diào)用相較 AMS 復(fù)雜的方法傳遞更具實(shí)際開發(fā)意義。

AMS 通知 Launcher 休眠.png

其中 performPauseActivity() 最終執(zhí)行了 Activity.onPause()

步驟3:AMS 啟動(dòng)目標(biāo) App 進(jìn)程

Launcher 休眠之后,通過(guò) IActivityManager 告知了 AMS,然后 AMS 就可以啟動(dòng)目標(biāo) Activity 了,但是在此之前,還需要判斷目標(biāo)程序的進(jìn)程是否已經(jīng)啟動(dòng),如果沒(méi)有啟動(dòng),則會(huì)做如下工作:

  1. AMS 通知 Zygote fork 一個(gè)應(yīng)用程序進(jìn)程。(不屬于文本重點(diǎn))
  2. AMS 創(chuàng)建 ActivityThread (UI 主線程),執(zhí)行 main 方法。這里的 main,就可以看作是 Java 入口的 main 函數(shù)。
  3. ActivityThread 線程中創(chuàng)建 Looper、Instrumentation、Application,并執(zhí)行 Application.onCreate。
  4. 通知 AMS,App 初始化完畢。

main 函數(shù)開始,進(jìn)入應(yīng)用程序進(jìn)程,所以下面流程圖也是從 main 方法開始。期間與 AMS 交互過(guò)程中 AMS 所在進(jìn)程的方法調(diào)用已省略。

AMS 啟動(dòng)目標(biāo) App 進(jìn)程.png

其中 ActivityThread.handleBindApplication 方法中創(chuàng)建了 Instrumentation、ContextImpl、Application,并間接調(diào)用了 Application.onCreate()

步驟4:AMS 啟動(dòng)目標(biāo) App 的 Activity

應(yīng)用程序進(jìn)程啟動(dòng)之后,就可以正常啟動(dòng) Activity 了。

步驟3 AMS 在調(diào)用 ApplicationThread.bindApplication() 之后,最終會(huì)調(diào)用app.thread.scheduleLaunchActivity(),將方法通過(guò) Binder 傳給 ApplicationThread.scheduleLaunchActivity(),其實(shí)際執(zhí)行方法為ActivityThread.handleLaunchActivity()。

之后將調(diào)用 ActivityThread.performLaunchActivity(),該方法將創(chuàng)建我們熟悉的 Context,并通過(guò) ClassLoader 創(chuàng)建 Activity,最終執(zhí)行 Activity.onCreate()。

ActivityThread.handleLaunchActivity() 還執(zhí)行了 Activity.onRestart()、Activity.onStart()Activity.onResume() 等熟悉的生命周期方法。

下面的流程圖包括了 Activity 創(chuàng)建運(yùn)行過(guò)程中非常重要的方法,關(guān)于 Activity 生命周期方法的執(zhí)行順序還可以參考 源碼分析 Activity 可見(jiàn)性真實(shí)時(shí)機(jī)。

AMS 啟動(dòng)目標(biāo) App 的 Activity.png

總結(jié)

以上就是 Launcher 啟動(dòng) App 過(guò)程中,應(yīng)用程序進(jìn)程涉及到的關(guān)鍵代碼。

熟悉以上流程可以幫助理解 Android 啟動(dòng)原理,為 Android 插件化、組件化鋪平道路。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容