引言
Activity啟動流程很多文章都已經說過了,這里說一下自己的理解。
Activity啟動流程分兩種:
- 一種是啟動正在運行的app的Activity,即啟動子Activity。如無特殊聲明默認和啟動該activity的activity處于同一進程。如果有聲明在一個新的進程中,則處于兩個進程。
- 一種是打開新的app,即為Launcher啟動新的Activity。
后邊啟動Activity的流程是一樣的,區別是前邊判斷進程是否存在的那部分。
Activity啟動的前提是已經開機,各項進程和AMS等服務已經初始化完成,在這里也提一下那些內容。
Activity啟動之前的一些事情
init進程:init是所有linux程序的起點,是Zygote的父進程。解析init.rc孵化出Zygote進程。
Zygote進程:Zygote是所有Java進程的父進程,所有的App進程都是由Zygote進程fork生成的。
SystemServer進程:System Server是Zygote孵化的第一個進程。SystemServer負責啟動和管理整個Java framework,包含AMS,PMS等服務。
-
Launcher:Zygote進程孵化的第一個App進程是Launcher。
1.init進程是什么?
Android是基于linux系統的,手機開機之后,linux內核進行加載。加載完成之后會啟動init進程。
init進程會啟動ServiceManager,孵化一些守護進程,并解析init.rc孵化Zygote進程。2.Zygote進程是什么?
所有的App進程都是由Zygote進程fork生成的,包括SystemServer進程。Zygote初始化后,會注冊一個等待接受消息的socket,OS層會采用socket進行IPC通信。
3.為什么是Zygote來孵化進程,而不是新建進程呢?
每個應用程序都是運行在各自的Dalvik虛擬機中,應用程序每次運行都要重新初始化和啟動虛擬機,這個過程會耗費很長時間。Zygote會把已經運行的虛擬機的代碼和內存信息共享,起到一個預加載資源和類的作用,從而縮短啟動時間。
Activity啟動階段
涉及到的概念
- 進程:Android系統為每個APP分配至少一個進程
- IPC:跨進程通信,Android中采用Binder機制。
涉及到的類
- ActivityStack:Activity在AMS的棧管理,用來記錄已經啟動的Activity的先后關系,狀態信息等。通過ActivityStack決定是否需要啟動新的進程。
- ActivitySupervisor:管理 activity 任務棧
- ActivityThread:ActivityThread 運行在UI線程(主線程),App的真正入口。
- ApplicationThread:用來實現AMS和ActivityThread之間的交互。
- ApplicationThreadProxy:ApplicationThread 在服務端的代理。AMS就是通過該代理與ActivityThread進行通信的。
- IActivityManager:繼承與IInterface接口,抽象出跨進程通信需要實現的功能
- AMN:運行在server端(SystemServer進程)。實現了Binder類,具體功能由子類AMS實現。
- AMS:AMN的子類,負責管理四大組件和進程,包括生命周期和狀態切換。AMS因為要和ui交互,所以極其復雜,涉及window。
- AMP:AMS的client端代理(app進程)。了解Binder知識可以比較容易理解server端的stub和client端的proxy。AMP和AMS通過Binder通信。
- Instrumentation:儀表盤,負責調用Activity和Application生命周期。測試用到這個類比較多。
流程圖
這個圖來源自網上,之前也看過很多類似講流程的文章,但是大都是片段的。這個圖是目前看到的最全的,自己去畫一下也應該不會比這個全了,所以在這里直接引用一下,可以去瀏覽器上放大看。
涉及到的進程
- Launcher所在的進程
- AMS所在的SystemServer進程
- 要啟動的Activity所在的app進程
如果是啟動根Activity,就涉及上述三個進程。
如果是啟動子Activity,那么就只涉及AMS進程和app所在進程。
具體流程
- Launcher:Launcher通知AMS要啟動activity。
- startActivitySafely->startActivity->Instrumentation.execStartActivity()(AMP.startActivity)->AMS.startActivity
- AMS:PMS的resoveIntent驗證要啟動activity是否匹配。
- 如果匹配,通過ApplicationThread發消息給Launcher所在的主線程,暫停當前Activity(Launcher);
- 暫停完,在該activity還不可見時,通知AMS,根據要啟動的Activity配置ActivityStack。然后判斷要啟動的Activity進程是否存在?
- 存在:發送消息LAUNCH_ACTIVITY給需要啟動的Activity主線程,執行handleLaunchActivity
- 不存在:通過socket向zygote請求創建進程。進程啟動后,ActivityThread.attach
- 判斷Application是否存在,若不存在,通過LoadApk.makeApplication創建一個。在主線程中通過thread.attach方法來關聯ApplicationThread。
- 在通過ActivityStackSupervisor來獲取當前需要顯示的ActivityStack。
- 繼續通過ApplicationThread來發送消息給主線程的Handler來啟動Activity(handleLaunchActivity)。
- handleLauchActivity:調用了performLauchActivity,里邊Instrumentation生成了新的activity對象,繼續調用activity生命周期。
IPC過程:
雙方都是通過對方的代理對象來進行通信。
1.app和AMS通信:app通過本進程的AMP和AMS進行Binder通信
2.AMS和新app通信:通過ApplicationThreadProxy來通信,并不直接和ActivityThread通信
參考函數流程
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所在進程執行)
- ActivityManagerService.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進程)
參考文章
http://gityuan.com/2016/03/12/start-activity/
https://blog.csdn.net/luoshengyang/article/details/6689748