今天要分析下fwk中activity的啓動流程,之前看別人畫的流程圖,總是很快就忘記了,而且總是摸不着重點,遇到具體問題時還是不知道從何入手,又得從頭看起。後來我想通了一件事,我們在分析這種源碼時不應該過渡糾結於流程圖與某個具體函數,而應該從宏觀角度想想:要實現這個功能,他應該要包含哪些步驟?
學習activity啓動流程時,請帶着這樣幾個問題去閱讀源碼:
- 新的activity是何時被創建的?進程內啓動activity與啓動一個新進程過程有什麼區別?
- 啓動activity時,當前的activity應該是要進到後臺的,那這個時間順序是怎樣的?這幾個activity的順序由誰來管理?
- 啓動過程中的切換動畫是什麼時候調用的?activity啓動後activity、window、application是什麼時候綁定在一起的?
這幾個問題的答案見我下面的標紅部分,希望能有助於大家在遇到實際問題時,能直接定位到相關節點去分析,節省時間。
目錄
具體流程
整個流程可以分爲兩大步驟:啓動前準備與真正啓動。
- 啓動前準備:在ActivityStarter和ActivityStackSupervisor 類中完成當前activity的暫停,並通知新的Activity的啓動;(涉及Intent解析,activity在棧中的進出。舊Activity.onPause--新Activity.onCreate-onStart-Resume--舊Activity.onStop。)
- 在ActivityThread中完成activity、application的創建和綁定,並調用界面顯示等;
具體流程如下:
- Activity的startActivity
- Instrumentation#execStartActivity
- ActivityManagerNative.getDefault().startActivity;(getDefault()返回的是ActivityManagerService的遠程接口ActivityManagerProxy,通過binder通信調用ActivityManagerService.startActivity。AMS通知ActivityThread是通過ApplicationThread(在frameworks/base/core/java/android/app/ActivityThread.java中)和ApplicationThreadProxy。)
- ActivityStarter.startActivityMayWait 中調用startActivityLocked;
- 解析Intent得到更多信息;
- 調用startActivityLocked;
- startActivity方法;
- startActivityUnchecked;
- ActivityStarter.startActivityUnchecked(實質會根據信息中launchMode,flag等來計算調度ActivityStack中的task,ActivityRecord等,);
- ActivityStack.startActivityLocked(源碼爲mTargetStack.startActivityLocked。將activity添加到棧頂,初始化WindowManager,回到StackSupervisor,調用StackSupervisor.resumeTopActivitiesLocked,再調回ActivityStack.resumeTopActivityLocked);
- WindowManagerService.prepareAppTransition 去準備activity跳轉動畫;
- 調用ActivityStack.startPausingLocked暫停交互當前Activity,裏面通過prev.app.thread.schedulePauseActivity調用ActivityThread.handlePauseActivity,接着調用performPauseActivityIfNeeded,然後是Instrumentation 的callActivityOnPause,調用activity.performPause();然後的onPause,然後調用ActivityManagerNative.getDefault()(獲取代理對象ActivityManagerProxy).activityPaused告訴ActivityManagerService 舊的Activity已經onPause,可以啓動新的Activity了。
- ActivityStack.startActivityLocked(源碼爲mTargetStack.startActivityLocked。將activity添加到棧頂,初始化WindowManager,回到StackSupervisor,調用StackSupervisor.resumeTopActivitiesLocked,再調回ActivityStack.resumeTopActivityLocked);
- ActivityStackSupervisor.startSpecificActivityLocked:(如果是新進程就調用startProcessLocked;如果不是就調用realStartActivityLocked)
- 在新進程中啓動時會執行到startProcessLocked(最終調用ActivityManagerService.startProcessLocked去創建新進程,主要是調用Process.start接口來創建一個新的進程,新的進程會導入android.app.ActivityThread類,並且執行它的main函數)
- ActivityThread.main調用attach方法,最終調到ActivityManagerService.attachApplicationLocked裏面,此時Process(並不是application)已經創建,就調用ActivityStackSupervisor.realStartActivityLocked(裏面也有更新Configuration)去真正啓動activity,最終調用到ActivityThread.handleLaunchActivity:
- ActivityThread.handleLaunchActivity;
- handleLaunchActivity:
- 解析前面傳過來的ActivityClientRecord,來收集activity的相關信息(是前面生成的);
- performLaunchActivity去實例化activity對象和application對象;
- 用mInstrumentation.newActivity去實例activity;
- 調用LoadedApk.makeApplication:去創建application對象(若使用了多進程,application對象會存在多個。);
- 創建Configuration;
- 調用activity.attach把activity、application和window關聯起來(需要用到Configuration);
- 設置應用theme主題;
- 通過調用mInstrumentation.callActivityOnCreate去調用Activity.performCreate,裏面可以調用onCreate;
- 調用mInstrumentation.callActivityOnRestoreInstanceState
- handleResumeActivity:
- performResumeActivity;
- Activity.performResume:
- performRestart:
- onResume:
- Activity.performResume:
- decor.setVisibility(View.INVISIBLE);此時視圖纔可見。
- performResumeActivity;
- handleLaunchActivity:
切換Activity窗口時Window變化的過程可參考:
https://blog.csdn.net/luoshengyang/article/details/8596449
相關類簡介
(參考:https://blog.csdn.net/ambitionsd/article/details/83342279):
ActivityManagerServices,簡稱AMS,服務端對象,負責系統中所有Activity的生命週期
ActivityThread,App的真正入口。當開啓App之後,會調用main()開始運行,開啓消息循環隊列,這就是傳說中的UI線程或者叫主線程。與ActivityManagerServices配合,一起完成Activity的管理工作
ApplicationThread,用來實現ActivityManagerService與ActivityThread之間的交互。在ActivityManagerService需要管理相關Application中的Activity的生命週期時,通過ApplicationThread的代理對象與ActivityThread通訊。
ApplicationThreadProxy,是ApplicationThread在服務器端的代理,負責和客戶端的ApplicationThread通訊。AMS就是通過該代理與ActivityThread進行通信的。
Instrumentation,每一個應用程序只有一個Instrumentation對象,每個Activity內都有一個對該對象的引用。Instrumentation可以理解爲應用進程的管家,ActivityThread要創建或暫停某個Activity時,都需要通過Instrumentation來進行具體的操作。
ActivityStack:這個並不是我們平時所說的任務棧,Activity在AMS的棧管理,用來記錄已經啓動的Activity的先後關係,狀態信息等。通過ActivityStack決定是否需要啓動新的進程。ActivityStack管理了一系列的TaskRecord,通過mStackId來唯一標識,持有ActivityStackSupervisor的引用。
ActivityRecord,ActivityStack的管理對象,每個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態以及其他的管理信息。其實就是服務器端的Activity對象的映像。
TaskRecord:這個纔是我們平時所說的任務棧,AMS抽象出來的一個“任務”的概念,是記錄ActivityRecord的棧,一個“Task”包含若干個ActivityRecord。AMS用TaskRecord確保Activity啓動和退出的順序。
ActivityStarter:啓動activity相關邏輯;
App與AMS通過Binder進行IPC通信,AMS(SystemServer進程)與zygote通過Socket進行IPC通信。
另外強烈推薦看下:https://www.jianshu.com/p/94816e52cd77
這篇文章詳細介紹了ActivityRecord、 TaskRecord,ActivityStack。