ActivityManagerService的啓動流程
介紹
這篇文章是講,從手機桌面(Launcher)點擊一個未啓動app的圖標到這個app啓動完成的流程(冷啓動)。android
整體流程
Launcher、AMS、Zygote、app都處於不一樣的進程,他們之間須要跨進程才能通訊。
數據庫
用戶點擊Launcher的app圖標後,Launcher通知AMS,若是目標app未啓動(冷啓動),AMS會經過Socket來通知Zygote去建立進程,Zygote就fork出咱們要啓動的app進程。
緊接着app要打開HomeActivity,須要與AMS交互
windows
- app -> AMS : 由於AMS啓動時,就註冊到ServiceManager了,因此app調用getService就能從ServiceManager獲取到AMS的代理類IActivityManager(客戶端)。app從而經過IActivityManager調用AMS(服務端)的方法。
- AMS -> app : AMS準備一個IBinder,叫IApplicationThread(服務端)。當app進程啓動完成後,會調用IApplicationThread的attachApplication方法,把app的代理類ApplicationThread(客戶端)做爲參數傳給AMS。AMS能夠調用ApplicationThread的方法從而控制app。
IApplicationThread的實現類是ActivityThread的內部類ApplicationThread數據結構
看完流程圖,咱們再來看時序圖
圖中的4就是attachApplication的過程,把app的代理類ApplicationThread交給AMS。
圖中的5就是AMS作完一些處理後,經過app的代理類ApplicationThread來啓動app的HomeActivity。
app
涉及的數據結構
在看源碼以前,須要先了解幾個重要的數據結構異步
ProcessRecord(進程)
第一類數據:描述身份的數據ide
- ApplicationInfo info:AndroidManifest.xml中定義的Application信息
- boolean isolated:是否是isolated進程
- int uid:進程uid
- int userId:這個是android作的多用戶系統id,就像windows能夠登陸不少用戶同樣,android也但願能夠實現相似的多用戶
- String processName:進程名字,默認狀況下是包名
- UidRecord uidRecord:記錄已經使用的uid
- IApplicationThread thread:這個很重要,它是ApplicationThread的客戶端,AMS就是經過這個對象給apk進程發送異步消息的(管理四大組件的消息),因此只有這個對象不爲空的狀況下,才表明apk進程可使用了
- int pid:進程的pid
- String procStatFile:proc目錄下每個進程都有一個以pid命名的目錄文件,這個目錄下記載着進程的詳細信息,這個目錄及目錄下的文件是內核建立的, proc是內核文件系統,proc就是process的縮寫,涉及的目的就是導出進程內核信息
- int[] gids:gid組
- CompatibilityInfo compat : 兼容性信息
- String requiredAbi : abi信息
- String instructionSet : 指令集信息
第二類數據:描述進程中組件的數據ui
- pkgList:進程中運行的包
- ArraySet pkgDeps:進程運行依賴的包
- ArrayList activities:進程啓動的全部的activity組件記錄表
- ArraySet services:進程啓動的全部的service組件記錄表
- ArraySet executingServices:正在運行(executing)是怎麼定義的?首先須要明確的是系統是怎麼控制組件的?發送消息給apk進程,apk進程處理消息,上報消息完成,這被定義爲一個完整的執行過程,所以正在執行(executing)被定義爲發送消息到上報完成這段時間
- ArraySet connections:綁定service的客戶端記錄表
- ArraySet receivers:廣播接收器的記錄表
- ContentProviderRecord pubProviders:pub是publish(發佈)的意思,ContentProvider須要安裝而後把本身發佈到系統(AMS)中後,才能使用,安裝指的是apk進程加載ContentProvider子類、初始化建立數據庫等過程,發佈是將ContentProvider的binder客戶端註冊到AMS中
- ArrayList conProviders:使用ContentProvider的客戶端記錄表
- BroadcastRecord curReceiver:當前進程正在執行的廣播 在本節中以上組件信息只是作一個簡單的描述,之後單獨分析組件管理的時候在詳細介紹
此外還有描述進程狀態的數據、和pss相關的數據、和時間相關的數據、crash和anr相關的數據、和instrumentation相關的數據、電源信息和調試信息等,spa
ActivityRecord
Activity在AMS內部是以ActivityRecord的形式存在的,Activity和ActivityRecord是一一對應的。線程
- ProcessRecord app:跑在哪一個進程
- TaskRecord task :跑在哪一個task
- ActivityInfo info :Activity信息
- int mActivityType:Activity類型
- ActivityState state:Activity狀態
- ApplicationInfo appInfo :跑在哪一個app
- ComponentName realActivity :組件名
- String packageName :包名
- String processName :進程名
- int launchMode:啓動模式
- int userId :該Activity運行在哪一個用戶id
mActivityType
- APPLICATION_ACTIVITY_TYPE:普通應用類型
- HOME_ACTIVITY_TYPE:桌面類型
- RECENTS_ACTIVITY_TYPE:最近任務類型
ActivityState
- INITIALIZING
- RESUMED:已恢復
- PAUSING
- PAUSED:已暫停
- STOPPING
- STOPPED:已中止
- FINISHING
- DESTROYING
- DESTROYED:已銷燬
ActivityRecord是在ActivityStarter的startActivity方法裏建立的
TaskRecord
任務棧TaskRecord,內部維護一個 ArrayList 用來保存ActivityRecord。
- ActivityStack stack:當前所屬的stack
- ArrayList mActivities:當前task的全部Activity列表
- int taskId
- String affinity:是指root activity的affinity,即該Task中第一個Activity
- int mCallingUid
- String mCallingPackage:調用者的包名
TaskRecord是在ActivityStarter的setTaskFromReuseOrCreateNewTask裏建立的。
ActivityStack
ActivityStack,內部維護了一個 ArrayList ,用來管理TaskRecord。
手機有三個虛擬按鍵,按最右邊的正方形按鍵,會顯示最近任務,這個最近任務就是一個ActivityStack,桌面應用也是一個ActivityStack。
ArrayList mTaskHistory //保存全部的Task列表
ArrayList mStacks; //全部stack列表
final int mStackId;
int mDisplayId;
ActivityRecord mPausingActivity //正在pause
ActivityRecord mLastPausedActivity
ActivityRecord mResumedActivity //已經resumed
ActivityRecord mLastStartedActivity
全部前臺stack的mResumedActivity的state == RESUMED, 則表示allResumedActivitiesComplete, 此時mLastFocusedStack = mFocusedStack;
ActivityStackSupervisor
ActivityStackSupervisor,顧名思義,就是用來管理ActivityStack的
- ActivityStack mHomeStack:桌面的stack
- ActivityStack mFocusedStack:當前聚焦stack
- ActivityStack mLastFocusedStack:正在切換
- SparseArray mActivityDisplays:displayId爲key
- SparseArray mActivityContainers: mStackId爲key
- home的棧ID等於0,即HOME_STACK_ID = 0;
ActivityStackSupervisor內部有兩個不一樣的ActivityStack對象:mHomeStack、mFocusedStack,用來管理不一樣的任務。
ActivityStackSupervisor內部包含了建立ActivityStack對象的方法。
AMS初始化時會建立一個ActivityStackSupervisor對象
詳細的流程
- Instrumentation:管理Activity的生命週期以及啓動
- ActivityManagerProxy:AMS的代理對象
- ApplicationThreadProxy:啓動APP的代理對象
- ApplicationThread是一個Binder服務,不是主線程
第9步是經過Handler來跨線程通訊,從子線程ApplicationThread走到主線程ActivityThread。