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

名詞說(shuō)明
Launcher:桌面應(yīng)用進(jìn)程;
AMS:ActivityManagerService,位于系統(tǒng) system_server 進(jìn)程中;
App:要啟動(dòng)的 App 進(jìn)程。
大致流程
流程上大體可分為四步:
- Launcher 通知 AMS 啟動(dòng) App。
- AMS 通知 Launcher 休眠。
- AMS 啟動(dòng)目標(biāo) App 進(jìn)程。
- AMS 啟動(dòng)目標(biāo) App 的 Activity。
詳細(xì)步驟
下面將分析每一步驟在 Android 應(yīng)用程序進(jìn)程中所做的事。
步驟1:Launcher 通知 AMS 啟動(dòng) App

如圖,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ā)意義。

其中 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ì)做如下工作:
- AMS 通知 Zygote fork 一個(gè)應(yīng)用程序進(jìn)程。(不屬于文本重點(diǎn))
- AMS 創(chuàng)建 ActivityThread (UI 主線程),執(zhí)行 main 方法。這里的 main,就可以看作是 Java 入口的 main 函數(shù)。
- ActivityThread 線程中創(chuàng)建 Looper、Instrumentation、Application,并執(zhí)行 Application.onCreate。
- 通知 AMS,App 初始化完畢。
從 main 函數(shù)開始,進(jìn)入應(yīng)用程序進(jìn)程,所以下面流程圖也是從 main 方法開始。期間與 AMS 交互過(guò)程中 AMS 所在進(jìn)程的方法調(diào)用已省略。

其中 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ī)。

總結(jié)
以上就是 Launcher 啟動(dòng) App 過(guò)程中,應(yīng)用程序進(jìn)程涉及到的關(guān)鍵代碼。
熟悉以上流程可以幫助理解 Android 啟動(dòng)原理,為 Android 插件化、組件化鋪平道路。