1 前言
日常開發過程中我們經常調用startActivity(..)啟動新的Activity,那么系統是如何找到這個Activity,Activity的啟動模式的啟動模式在什么地方發揮作用,以及如何控制兩個Activity的生命周期的,這些值得深入源碼中去探索下。
2 Activity啟動整體過程
- 點擊桌面app圖標,Launcher進程采用Binder IPC向system_server進程發起startActivity請求;
- system_server進程接收到請求后,向zygote進程發送創建新進程的請求;
- zygote進程fork出新的子進程,即App進程;
- App進程通過Binder IPC向system_server進程發起attach Application請求;
- system_server收到請求后,進行一系列的準備后,再通過Binder IPC向App進程發送scheduleLaunchActivity請求;
- App進程的ApplicationThread收到請求后,通過handler向主線程發送LAUNCH_ACTIVITY消息;
- 主線程在收到Message后,創建目標Activity,并回調Activity.onCreate()等方法;
注意:App與AMS通過Binder進行IPC通信,AMS(SystemServer進程)與zygote通過Socket進行IPC通信,Zygote創建一個套接字,監聽ams發過來的fork請求。
2.1 啟動過程涉及的主要類
frameworks/base/services/core/java/com/android/server/am/
- ActivityManagerService.java
- ActivityStackSupervisor.java
- ActivityStack.java
- ActivityRecord.java
- ProcessRecord.java
frameworks/base/core/java/android/app/
- IActivityManager.java
- ActivityManagerNative.java (內含ActivityManagerProxy)
- ActivityManager.java
- IApplicationThread.java
- ApplicationThreadNative.java (內含ApplicationThreadProxy)
- ActivityThread.java (內含ApplicationThread)
- Instrumentation.java
- ContextImpl.java
ActivityManagerServices
簡稱AMS,服務端對象,負責系統中所有Activity的生命周期。ActivityStackSupervisor
管理activity任務棧,內部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關的Activity棧;mFocusedStack管理的是當前顯示在前臺Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前臺Activity的Activity棧。ActivityStack
Activity在AMS的棧管理,用來記錄已經啟動的Activity的先后關系,狀態信息等。通過ActivityStack決定是否需要啟動新的進程。ActivityRecord
ActivityStack的管理對象,每個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態以及其他的管理信息,其實就是服務器端的Activity對象的映像。TaskRecord
AMS抽象出來的一個“任務”的概念,是記錄ActivityRecord的棧,一個“Task”包含若干個ActivityRecord。AMS用TaskRecord確保Activity啟動和退出的順序。如果你清楚Activity的4種launchMode,那么對這個概念應該不陌生。
ApplicationThread
用來實現AMS和ActivityThread之間的交互。在AMS需要管理相關Application中的Activity的生命周期時,通過ApplicationThread的代理對象與ActivityThread通訊。ApplicationThreadProxy
ApplicationThread 在服務端的代理,AMS就是通過該代理與ActivityThread進行通信的。ActivityThread
App的真正入口,當開啟App之后,會調用main()開始運行,開啟消息循環隊列,這就是傳說中的UI線程或者叫主線程。與ActivityManagerServices配合,一起完成Activity的管理工作。Instrumentation
儀表盤,每一個應用程序只有一個Instrumentation對象,每個Activity內都有一個對該對象的引用。負責調用
Activity和Application生命周期。測試用到這個類比較多。AMS是董事會,負責指揮和調度的,ActivityThread是老板,雖然說家里的事自己說了算,但是需要聽從AMS的指揮,而Instrumentation則是老板娘,負責家里的大事小事,但是一般不拋頭露面,聽一家之主ActivityThread的安排。
3 Activity啟動過程階段
Activity啟動流程(從Launcher開始):
第一階段: Launcher通知AMS要啟動新的Activity(在Launcher所在的進程執行)
- Launcher.startActivitySafely //首先Launcher發起啟動Activity的請求
- Activity.startActivity
- Activity.startActivityForResult
- Instrumentation.execStartActivity //交由Instrumentation代為發起請求
- ActivityManager.getService().startActivity //通過IActivityManagerSingleton.get()得到一個AMP代理對象
- ActivityManagerProxy.startActivity //通過AMP代理通知AMS啟動activity
第二階段:AMS先校驗一下Activity的正確性,如果正確的話,會暫存一下Activity的信息。然后,AMS會通知Launcher程序pause Activity(在AMS所在進程執行)
- ctivityManagerService.startActivity
- ActivityManagerService.startActivityAsUser
- ActivityStackSupervisor.startActivityMayWait
- ActivityStackSupervisor.startActivityLocked :檢查有沒有在AndroidManifest中注冊
- ActivityStackSupervisor.startActivityUncheckedLocked
- ActivityStack.startActivityLocked :判斷是否需要創建一個新的任務來啟動Activity。
- ActivityStack.resumeTopActivityLocked :獲取棧頂的activity,并通知Launcher應該pause掉這個Activity以便啟動新的activity。
- ActivityStack.startPausingLocked
- ApplicationThreadProxy.schedulePauseActivity
第三階段: pause Launcher的Activity,并通知AMS已經paused(在Launcher所在進程執行)
- ApplicationThread.schedulePauseActivity
- ActivityThread.queueOrSendMessage
- H.handleMessage
- ActivityThread.handlePauseActivity
- ActivityManagerProxy.activityPaused
第四階段:檢查activity所在進程是否存在,如果存在,就直接通知這個進程,在該進程中啟動Activity;不存在的話,會調用Process.start創建一個新進程(執行在AMS進程)
- ActivityManagerService.activityPaused
- ActivityStack.activityPaused
- ActivityStack.completePauseLocked
- ActivityStack.resumeTopActivityLocked
- ActivityStack.startSpecificActivityLocked
- ActivityManagerService.startProcessLocked
- Process.start //在這里創建了新進程,新的進程會導入ActivityThread類,并執行它的main函數
第五階段: 創建ActivityThread實例,執行一些初始化操作,并綁定Application。如果Application不存在,會調用LoadedApk.makeApplication創建一個新的Application對象。之后進入Loop循環。(執行在新創建的app進程)
- ActivityThread.main
- ActivityThread.attach(false) //聲明不是系統進程
- ActivityManagerProxy.attachApplication
第六階段:處理新的應用進程發出的創建進程完成的通信請求,并通知新應用程序進程啟動目標Activity組件(執行在AMS進程)
- ActivityManagerService.attachApplication //AMS綁定本地ApplicationThread對象,后續通過ApplicationThreadProxy來通信。
- ActivityManagerService.attachApplicationLocked
- ActivityStack.realStartActivityLocked //真正要啟動Activity了!
- ApplicationThreadProxy.scheduleLaunchActivity //AMS通過ATP通知app進程啟動Activity
第七階段: 加載MainActivity類,調用onCreate聲明周期方法(執行在新啟動的app進程)
- ApplicationThread.scheduleLaunchActivity //ApplicationThread發消息給AT
- ActivityThread.queueOrSendMessage
- H.handleMessage //AT的Handler來處理接收到的LAUNCH_ACTIVITY的消息
- ActivityThread.handleLaunchActivity
- ActivityThread.performLaunchActivity
- Instrumentation.newActivity //調用Instrumentation類來新建一個Activity對象
- Instrumentation.callActivityOnCreate
- MainActivity.onCreate
- ActivityThread.handleResumeActivity
- AMP.activityResumed
- AMS.activityResumed(AMS進程)
4 Activity啟動代碼分析
Activity的啟動過程主要會涉及五個進程:Launcher進程、System_server進程、當前的前臺進程、待啟動的Activity所在進程、Zygote進程, 在上圖中已有所體現。
具體源碼分析見參考資料[5]和[10]
參考資料:
[1] Activity啟動流程 ★
[2] Activity 啟動全過程解析 ★
[3] Android的Activity啟動流程分析 ★
[4] Activity 啟動流程 √
[5] 一張圖表示Activity啟動流程-- Activity啟動流程詳解 ★★
[6] 3分鐘看懂Activity啟動流程 √
[7] 說說Activity的啟動流程 ★
[8] Android進程啟動過程 & Activity顯示過程 √
[9] 庖丁解牛 Activity 啟動流程 √
[10] startActivity啟動過程分析