面試官:什麼是應用程序啓動
應用程序的啓動,又可稱爲根Activity的啓動。但是在講應用程序啓動之前,我們有必要對應用程序進程(AppProcess)啓動有所瞭解,那是因爲啓動一個應用程序首先要保證該應用程序的進程已經被啓動。AMS在啓動應用程序時,會先檢查應用程序進程是否存在,如果不存在就需要請求Zygote進程創建並啓動應用程序進程。這裏我不會貼上大段大段的代碼,只是一些總結,並提供了相關源碼的鏈接。
應用程序進程(AppProcess)啓動
啓動大綱
- AMS發送啓動應用程序進程請求.
- Zygote接收請求並創建應用程序進程.
AMS發送啓動應用程序進程請求
-
AMS通過調用startProcessLocked方法向Zygote進程發送請求。
-
Process調用
start
方法,使用ZygoteProcess的start
方法。 - 在ZygoteProcess的
start
方法中,先後調用了startViaZygote
、zygoteSendArgsAndGetResult
和openZygoteSocketIfNeeded
等方法,最後在openZygoteSocketIfNeeded
方法中調用了ZygoteState的connect方法建立與Zygote進程的連接。
AMS發送啓動應用程序進程請求
-
ZygoteServer執行
runSelectLoop
方法,一直等待AMS的請求數據到來。 -
當AMS請求到來,與Zygote進程建立連接後,由ZygoteConnection的
processOneCommand
方法處理請求的數據。對請求數據進行解析,獲取程序進程的啓動參數,並通過Zygote的forkAndSpecialize
方法進行應用程序進程的創建。 -
進程創建完成後,交由ZygoteInit的
zygoteInit
方法和RuntimeInit的applicationInit
方法分別進行進程和應用的初始化。在zygoteInit
方法中,爲應用程序進程創建了Binder線程池,這樣進程就可以跨進程進行通信了。而applicationInit
方法通過反射最終會調用ActivityThread的main
方法,從而完成應用程序進程的創建。 -
- *
應用程序(App)啓動
講完了應用程序進程(AppProcess)啓動的相關內容後,接下來我們就來看看應用程序是如何一步一步啓動的。
啓動大綱
- Launcher請求AMS。
- AMS請求ApplicationThread。
- ActivityThread啓動Activity。
啓動時序圖
Launcher請求AMS
-
當我們點擊應用程序的圖標時,就會自動調用Launcher的
startActivitySafely
方法, 最終會調用Activity的startActivity
方法。 -
在Activity的
startActivity
中又調用了startActivityForResult
方法,而startActivityForResult
方法內部又調用了Instrumentation的execStartActivity
方法。 - 在Instrumentation的
execStartActivity
方法中又通過ActivityManager的getService
方法獲取了IBinder類型的AMS引用IActivityManager
,最後調用了AMS的startActivity
方法。
AMS請求ApplicationThread
-
在AMS的
startActivity
方法中,又調用了其本身的startActivityAsUser
方法,進行權限的檢查。 -
權限檢查完後,調用ActivityStarter的
startActivityMayWait
方法,並在該方法中解析處理應用程序需要的參數,並進行相關參數的初始化,最終會調用其startActivity
方法。而在startActivity
方法中又調用了startActivityUnchecked
方法來處理與棧管理相關的邏輯。 -
在處理完棧的關係後,緊接着會調用ActivityStackSupervisor的
resumeFocusedStackTopActivityLocked
方法獲取需要啓動的Activity所在棧的棧頂。 -
當需要啓動的Activity的狀態不是RESUMED狀態,就需要調用ActivityStack的
resumeTopActivityUncheckedLocked
方法,而它的內部又調用了resumeTopActivityInnerLocked
方法進行一系列的棧狀態的判斷,最終又回調了ActivityStackSupervisor的startSpecificActivityLocked
方法。 -
在ActivityStackSupervisor的
startSpecificActivityLocked
方法中先是獲取了即將啓動的Activity所在的應用程序進程(就是在這個地方判斷應用所在進程是否存在且已啓動,如果沒有啓動,就需要啓動應用程序進程),然後調用realStartActivityLocked
方法。 - 在ActivityStackSupervisor的
realStartActivityLocked
方法中,對啓動的應用程序進程進行一系列的判斷和處理,最終會調用IBinder類型的ApplicationThread引用IApplicationThread
,通過傳入IApplicationThread
建立ClientTransaction
,加入執行LaunchActivityItem
任務,最終實現跨進程執行調用ActivityThread的handleLaunchActivity
方法。
ActivityThread啓動Activity
-
在ActivityThread調用了它的
handleLaunchActivity
方法中,會先調用其performLaunchActivity
方法,之後調用handleResumeActivity
,將Activity的狀態置爲Resume。 - 在ActivityThread的performLaunchActivity方法中做了很多事情。
- 首先,執行了
createBaseContextForActivity
方法,創建要啓動Activity的上下文; - 其次,調用執行了Instrumentation的
newActivity
方法來創建Activity實例; - 接着,調用LoadedApk的
makeApplication
方法,創建應用程序的Application; - 之後,調用需要啓動的Activity的
attach
方法初始化Activity,創建Window對象並與Activity自身進行關聯。 - 最後,調用執行了Instrumentation的
callActivityOnCreate
方法來啓動Activity。
- 在Instrumentation執行了
callActivityOnCreate
方法中,會調用Activity的performCreate
方法,最終會調用Activity的onCreate
方法,這樣應用程序也就啓動了。
應用程序啓動的進程關係圖
應用程序啓動的過程中,主要涉及了Launcher進程、SystemServer進程、Zygote進程和應用程序進程這四個進程,它們之間的關係如下。
總結
好了,今天的分享就到這裏,如果你對在面試中遇到的問題,或者剛畢業及工作幾年迷茫不知道該如何準備面試並突破現狀提升自己,對於自己的未來還不夠了解不知道給如何規劃,可以簡信我獲取一下相關面試題及答案資料包及學習視頻。
專注分享大型Bat面試知識,後續會持續更新,希望通過這些高級面試題能夠降低面試Android崗位的門檻,讓更多的Android工程師理解Android系統,掌握Android系統。喜歡的話麻煩點擊一個喜歡在關注一下~