Android的Activity啟動過程分析

<code>http://www.lgygg.wang/lgyblog/2020/03/10/androidactivity%e5%90%af%e5%8a%a8%e8%bf%87%e7%a8%8b%e5%88%86%e6%9e%90/
/<code>

1.前提

本文的圖片如果沒有特別說明Android SDK的版本,則默認使用的是Android 6.0(SDK23),不知道版本的會在文末給出源碼鏈接。

2.落筆緣由

關於Activity的啟動過程在網上其實已經有比較詳細的文章,本來打算轉載過來,但是由於作者並沒有說明可不可以轉載,所以只能寫一篇文章來記錄一下當時我的分析過程。

3.App啟動過程分析

Android的Activity啟動過程分析

1)創建進程

每個App都會擁有一個單獨的進程,下面分析一下進程創建的過程。下圖是網上找到的圖片,介紹了App啟動的過程。圖中,可以看出,Launcher(桌面,即我們看到的手機桌面,它也是一個App。因為Android定製廠商太多,所以並不是所有的手機廠商的Launcher都是一樣的,只能在網上搜索Launcher.java的源碼,該源碼的地址會在文章末尾給出,我只給出出處,對錯讀者自行分辨),Zogote和AcctivityManagerService都會伴隨著系統的啟動而運行著。1.當用戶點擊Launcher上的App圖標的時候,就會觸發裡面的事件,調用Launcher的startActivity方法,通過進程間通信,在Launcher的startActivity裡調用了ActivityManagerService(它在另一個進程裡,所以需要通過進程間通信來調用)裡的startActivity方法。如圖是Launcher.java的源碼

Android的Activity啟動過程分析

Launcher也是一個Activity,下面看到OnClick方法,觀察它如何處理點擊事件

Android的Activity啟動過程分析

點擊桌面的圖標的時候,調用的其實是Launcher的startActivitySafely方法,再到startActivitySafely看,發現它調用了startActivity方法

Android的Activity啟動過程分析

“通過Binder IPC機制, 最終調用到ActivityManagerService”是一個什麼過程?上面我們已經分析到“調用Launcher的startActivity方法”,因為Launcher是繼承了Activity,所以直接看Acitivty的源碼

Android的Activity啟動過程分析

發現調用了startActivityForResult方法,到startActivityForResult裡,看它調用了Instrumentation類的execStartActivity方法

Android的Activity啟動過程分析

然後execStartActivity裡,這是Android6.0(SDK 23)的代碼,

Android的Activity啟動過程分析

可以看到它調用了ActivityManagerService的startActivity,也許你會說明明是ActivityManagerNative,和ActivityManagerService有什麼關係?再看一下ActivityManagerService,會發現ActivityManagerService繼承了ActivityManagerNative

Android的Activity啟動過程分析

但是到了Adndroid8.0(SDK 26),會發現它不用ActivityManagerNative了,而是ActivityTaskManager,但應該是一樣的,最後都調用的是ActivityManagerService服務的startActivity方法。

Android的Activity啟動過程分析

然後對於這三句話,我在Android6.0(SDK23)裡找不到PackageManager的resolveIntent方法(我看了一下原作者的文章,是2010年發表的,所以可能是因為原作者的SDK版本比較舊,所以我這裡對不上)

2.然後ActivityManagerService就會處理Launcher的startActivity裡傳過來的Intent,判斷是否有權限啟動這個App,如果有,則創建一個新的Task。3.接著ActivityManagerService調用startProcessLocked()方法來創建新的進程, 該方法會通過socket通道傳遞參數給Zygote進程. Zygote孵化自身, 並調用ZygoteInit.main()方法來實例化ActivityThread對象並最終返回新進程的pid。

創建進程的流程圖如下(這個流程使用的代碼應該是Android2.3的),雖然最新的已經到了Android10了,但是我覺得大概流程應該是一致的。

Android的Activity啟動過程分析

2)綁定Application

這個綁定過程主要是在ActivityThread裡進行。流程圖如下

Android的Activity啟動過程分析

通過ActivityThread調用bindApplication來完成的。此方法將BIND_APPLICATION消息發送到消息隊列。

Android的Activity啟動過程分析

隨後ActivityThread裡的handleMessage()方法接受到要處理的消息然後調用handleBindApplication()方法。

Android的Activity啟動過程分析

此方法調用makeApplication()方法,該方法將應用程序特定的類加載到內存中。

3)啟動Activity

通過上面的步驟,已經為這個App創建了一個進程。《Android Application Launch》文中描述的是“啟動過程從ActivityManagerService的realStartActivity()方法開始,該方法在應用程序線程對象上調用sheduleLaunchActivity()。此方法將LAUNCH_ACTIVITY消息發送到消息隊列。該消息由handleLaunchActivity()方法處理”。在本地SDK我實在找不到ActivityManagerService的源碼,所以我在網上查找到的源碼我也不知道是什麼版的,但是會在結尾給出鏈接。在這個ActivityManagerService裡,我找不到realStartActivity方法,通過全文搜索,我只找到了startActivityLocked方法,這個方法是ActivityStackSupervisor裡的。下面我們順著之前的代碼來進行,Instrumentation的實例調用了execStartActivity方法,之後的操作調用如下

Android的Activity啟動過程分析

ActivityManagerNative可以看到,調用了ActivityStackSupervisor的startActivityMayWait方法

Android的Activity啟動過程分析

ActivityStackSupervisor的startActivityMayWait方法裡調用了startActivityLocked

Android的Activity啟動過程分析

startActivityLocked裡調用了startActivityUncheckedLocked

Android的Activity啟動過程分析

接著startActivityUncheckedLocked裡調用了ActivityStack的startActivityLocked

Android的Activity啟動過程分析

然後調用ActivityStackSupervisor的resumeTopActivitiesLocked方法

Android的Activity啟動過程分析

而ActivityStackSupervisor的resumeTopActivitiesLocked方法調用了ActivityStack的resumeTopActivityLocked

Android的Activity啟動過程分析

ActivityStack的resumeTopActivityLocked又調用自己的resumeTopActivityInnerLocked方法

Android的Activity啟動過程分析

resumeTopActivityInnerLocked調用了ActivityStackSupervisor的startSpecificActivityLocked

Android的Activity啟動過程分析

而startSpecificActivityLocked裡調用了realStartActivityLocked

Android的Activity啟動過程分析

realStartActivityLocked方法調用了ActivityThread的scheduleLaunchActivity方法

Android的Activity啟動過程分析

來到ActivityThread的scheduleLaunchActivity方法,發送了一個LAUNCH_ACTIVITY消息,

Android的Activity啟動過程分析

ActivityThread的handlerMessage裡,如下圖,調用了handlerLaunchActivity

Android的Activity啟動過程分析

在handlerLaunchActivity裡通過Instrumentation的newActivity方法創建Activity,然後通過performLaunchActivity方法裡的Instrumentation的callActivityOnCreate方法來調用Activity的onCreate方法

Android的Activity啟動過程分析

到這裡,App的啟動過程就結束了。這是《Android Application Launch》文中的流程圖,展示了一個App的launcher Activity的啟動流程,注意《Android Application Launch》文中是基於比較舊的SDK(應該是Android2.3)來分析的,所有會有一些類對不上,但是大體流程變化不大,還是有一定的意義的。

Android的Activity啟動過程分析

4.補充

之前一直不知道ActivityManagerService.java在哪,所有隻能科學上網去找,後面發現它還是在SDK裡,路徑是C:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\sources\\android-23\\com\\android\\server\\am從路徑可以看出我查看的是Android SDK23(Android6.0)的源碼。

Android的Activity啟動過程分析

不僅是ActivityManagerService.java,ActivityStack.java和ActivityStackSupervisor.java都在這個路徑下。本文所有的圖中沒標註的,都是文章末尾的“參考文章”給出的鏈接中截取的圖,我和SDK裡的對照了一下,發現改動並不大,就不對上面的圖進行替換了。

5.參考文章

<code>ActivityManagerService.java:
https://android.googlesource.com/platform/frameworks/base/+/4f868ed/services/core/java/com/android/server/am/ActivityManagerService.java
ActivityStack.java:
https://android.googlesource.com/platform/frameworks/base/+/4f868ed/services/core/java/com/android/server/am/ActivityStack.java
ActivityStackSupervisor.java:
https://android.googlesource.com/platform/frameworks/base/+/4f868ed/services/core/java/com/android/server/am/ActivityStackSupervisor.java
Launcher.java:
https://android.googlesource.com/platform/packages/apps/Launcher3/+/815ba2d/src/com/android/launcher2/Launcher.java
一篇分析App啟動過程的文章,原文標題《Android 6.0 Launcher啟動活動過程源碼分析(一)》:
https://glumes.com/post/android/android-start-activity-from-launcher-1/
分析Activity的啟動過程,原文標題《Android的Activity啟動流程》:
https://www.jianshu.com/p/75ed670debf0
《Android Application Launch》:
http://multi-core-dump.blogspot.com/2010/04/android-application-launch.html
http://multi-core-dump.blogspot.com/2010/04/android-application-launch-part-2.html
《Android Application Launch》譯文:
https://www.jianshu.com/p/a5532ecc8377/<code>


分享到:


相關文章: