APP和activity啟動流程

整個 startActivity 的流程分為?3?大部分,也涉及?3?個進程之間的交互:

ActivityA --> ActivityManagerService(簡稱?AMS)

ActivityManagerService --> ApplicationThread

ApplicationThread --> Activity

ActivityA --> ActivityManagerService?階段

這一過程并不復(fù)雜,用一張圖表示具體過程如下:

Activity 的?startActivity

最終調(diào)用了 startActivityForResult 方法,傳入的?-1?表示不需要獲取?startActivity?的結(jié)果。

Activity 的?startActivityForResult

startActivityForResult 也很簡單,調(diào)用?Instrumentation.execStartActivity?方法。剩下的交給?Instrumentation?類去處理。

解釋說明:

Instrumentation 類主要用來監(jiān)控應(yīng)用程序與系統(tǒng)交互。

藍框中的 mMainThread 是?ActivityThread?類型,ActivityThread?可以理解為一個進程,在這就是?A?所在的進程。

通過 mMainThread 獲取一個?ApplicationThread?的引用,這個引用就是用來實現(xiàn)進程間通信的,具體來說就是?AMS?所在系統(tǒng)進程通知應(yīng)用程序進程進行的一系列操作。

app進程通過ActivityManager.getService?(高版本)或者?ActivityManagerNative.getDefault(低版本)返回的IActivityManager來調(diào)用系統(tǒng)進程AMS中的方法。該IActivityManager是AMS在app進程的binder代理對象

同樣,系統(tǒng)進程通過ProcessRecord.IApplicationThread調(diào)用app進程相關(guān)方法。IApplicationThread是系統(tǒng)進程持有的app進程中ApplicationThread的Binder代理對象。

AMS通過binder代理調(diào)用到ApplicationThread(ActivityThread的內(nèi)部類)中的方法后,通過主線程(ActivityThread中的main方法)中開啟的handler消息輪詢來通知主線程調(diào)用相關(guān)方法。主線程的相關(guān)聲明周期方法的具體實現(xiàn)會委托給Instrumentation類實現(xiàn),在Instrumentation類中,會調(diào)用具體組件的相關(guān)生命周期方法。

Activity啟動之前的一些事情

init進程:init是所有l(wèi)inux程序的起點,是Zygote的父進程。解析init.rc孵化出Zygote進程。

Zygote進程:Zygote是所有Java進程的父進程,所有的App進程都是由Zygote進程fork生成的。

SystemServer進程:System Server是Zygote孵化的第一個進程。SystemServer負(fù)責(zé)啟動和管理整個Java framework,包含AMS,PMS等服務(wù)。

Launcher:Zygote進程孵化的第一個App進程是Launcher。

1.init進程是什么?

Android是基于linux系統(tǒng)的,手機開機之后,linux內(nèi)核進行加載。加載完成之后會啟動init進程。

init進程會啟動ServiceManager,孵化一些守護進程,并解析init.rc孵化Zygote進程。

2.Zygote進程是什么?

所有的App進程都是由Zygote進程fork生成的,包括SystemServer進程。Zygote初始化后,會注冊一個等待接受消息的socket,OS層會采用socket進行IPC通信。

3.為什么是Zygote來孵化進程,而不是新建進程呢?

每個應(yīng)用程序都是運行在各自的Dalvik虛擬機中,應(yīng)用程序每次運行都要重新初始化和啟動虛擬機,這個過程會耗費很長時間。Zygote會把已經(jīng)運行的虛擬機的代碼和內(nèi)存信息共享,起到一個預(yù)加載資源和類的作用,從而縮短啟動時間。

Activity啟動階段

涉及到的概念

進程:Android系統(tǒng)為每個APP分配至少一個進程

IPC:跨進程通信,Android中采用Binder機制。

涉及到的類

ActivityStack:Activity在AMS的棧管理,用來記錄已經(jīng)啟動的Activity的先后關(guān)系,狀態(tài)信息等。通過ActivityStack決定是否需要啟動新的進程。

ActivitySupervisor:管理?activity?任務(wù)棧

ActivityThread:ActivityThread?運行在UI線程(主線程),App的真正入口。

ApplicationThread:用來實現(xiàn)AMS和ActivityThread之間的交互。

ApplicationThreadProxy:ApplicationThread?在服務(wù)端的代理。AMS就是通過該代理與ActivityThread進行通信的。

IActivityManager:繼承與IInterface接口,抽象出跨進程通信需要實現(xiàn)的功能

AMN:運行在server端(SystemServer進程)。實現(xiàn)了Binder類,具體功能由子類AMS實現(xiàn)。

AMS:AMN的子類,負(fù)責(zé)管理四大組件和進程,包括生命周期和狀態(tài)切換。AMS因為要和ui交互,所以極其復(fù)雜,涉及window。

AMP:AMS的client端代理(app進程)。了解Binder知識可以比較容易理解server端的stub和client端的proxy。AMP和AMS通過Binder通信。

Instrumentation:儀表盤,負(fù)責(zé)調(diào)用Activity和Application生命周期。測試用到這個類比較多。

ActivityStackSupervisor

負(fù)責(zé)所有Activity棧的管理。內(nèi)部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關(guān)的Activity棧;mFocusedStack管理的是當(dāng)前顯示在前臺Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前臺Activity的Activity棧。

ActivityThread.java??路徑位于:\frameworks\base\core\java\android\app\ActivityThread.java

說明:該類為應(yīng)用程序(即APK包)所對應(yīng)進程(一個進程里可能有多個應(yīng)用程序)的主線程類,即我們通常所說的UI線程。

一個ActivityThread類對應(yīng)于一個進程。最重要的是,每個應(yīng)用程序的入口是該類中的static main()函數(shù) 。

Instrumentation.java路徑位于 :\frameworks\base\core\java\android\app\ActivityThread.java

說明:該類用于具體操作某個Activity的功能----單向(oneway)調(diào)用AMS以及統(tǒng)計、測量該應(yīng)用程序的所有開銷。

一個Instrumentation類對應(yīng)于一個進程。每個Activity內(nèi)部都有一個該Instrumentation對象的引用。

舉個例子吧。

我們將我們應(yīng)用程序比作一個四合院,那么Activity對應(yīng)于四合院的人,ActivithThread對應(yīng)于院子的主人----管理所有人,

Instrumentation對應(yīng)于管家------受氣的命,接受來自人(Activity/ActivithThread)的命令 ,去單向(oneway)調(diào)用AMS?。

ApplicationThread類是ActivityThread的內(nèi)部類:

說明:該類是一個Binder類,即可實現(xiàn)跨進程通信。主要用于接受從AMS傳遞過來的消息,繼而做相應(yīng)處理。

具體流程

Launcher:Launcher通知AMS要啟動activity。

startActivitySafely->startActivity->Instrumentation.execStartActivity()(AMP.startActivity)->AMS.startActivity

AMS:PMS的resoveIntent驗證要啟動activity是否匹配。

如果匹配,通過ApplicationThread發(fā)消息給Launcher所在的主線程,暫停當(dāng)前Activity(Launcher);

暫停完,在該activity還不可見時,通知AMS,根據(jù)要啟動的Activity配置ActivityStack。然后判斷要啟動的Activity進程是否存在?

存在:發(fā)送消息LAUNCH_ACTIVITY給需要啟動的Activity主線程,執(zhí)行handleLaunchActivity

不存在:通過socket向zygote請求創(chuàng)建進程。進程啟動后,ActivityThread.attach

判斷Application是否存在,若不存在,通過LoadApk.makeApplication創(chuàng)建一個。在主線程中通過thread.attach方法來關(guān)聯(lián)ApplicationThread。

在通過ActivityStackSupervisor來獲取當(dāng)前需要顯示的ActivityStack。

繼續(xù)通過ApplicationThread來發(fā)送消息給主線程的Handler來啟動Activity(handleLaunchActivity)。

handleLauchActivity:調(diào)用了performLauchActivity,里邊Instrumentation生成了新的activity對象,繼續(xù)調(diào)用activity生命周期。

IPC過程:

雙方都是通過對方的代理對象來進行通信。

1.app和AMS通信:app通過本進程的AMP和AMS進行Binder通信

2.AMS和新app通信:通過ApplicationThreadProxy來通信,并不直接和ActivityThread通信

參考函數(shù)流程

Activity啟動流程(從Launcher開始):

第一階段:Launcher通知AMS要啟動新的Activity(在Launcher所在的進程執(zhí)行)

Launcher.startActivitySafely //首先Launcher發(fā)起啟動Activity的請求

Activity.startActivity

Activity.startActivityForResult

Instrumentation.execStartActivity //交由Instrumentation代為發(fā)起請求

ActivityManager.getService().startActivity //通過IActivityManagerSingleton.get()得到一個AMP代理對象

ActivityManagerProxy.startActivity //通過AMP代理通知AMS啟動activity

第二階段:AMS先校驗一下Activity的正確性,如果正確的話,會暫存一下Activity的信息。然后,AMS會通知Launcher程序pause Activity(在AMS所在進程執(zhí)行)

ActivityManagerService.startActivity

ActivityManagerService.startActivityAsUser

ActivityStackSupervisor.startActivityMayWait

ActivityStackSupervisor.startActivityLocked :檢查有沒有在AndroidManifest中注冊

ActivityStackSupervisor.startActivityUncheckedLocked

ActivityStack.startActivityLocked :判斷是否需要創(chuàng)建一個新的任務(wù)來啟動Activity。

ActivityStack.resumeTopActivityLocked :獲取棧頂?shù)腶ctivity,并通知Launcher應(yīng)該pause掉這個Activity以便啟動新的activity。

ActivityStack.startPausingLocked

ApplicationThreadProxy.schedulePauseActivity

第三階段:pause Launcher的Activity,并通知AMS已經(jīng)paused(在Launcher所在進程執(zhí)行)

ApplicationThread.schedulePauseActivity

ActivityThread.queueOrSendMessage

H.handleMessage

ActivityThread.handlePauseActivity

ActivityManagerProxy.activityPaused

第四階段:檢查activity所在進程是否存在,如果存在,就直接通知這個進程,在該進程中啟動Activity;不存在的話,會調(diào)用Process.start創(chuàng)建一個新進程(執(zhí)行在AMS進程)

ActivityManagerService.activityPaused

ActivityStack.activityPaused

ActivityStack.completePauseLocked

ActivityStack.resumeTopActivityLocked

ActivityStack.startSpecificActivityLocked

ActivityManagerService.startProcessLocked

Process.start //在這里創(chuàng)建了新進程,新的進程會導(dǎo)入ActivityThread類,并執(zhí)行它的main函數(shù)

第五階段:創(chuàng)建ActivityThread實例,執(zhí)行一些初始化操作,并綁定Application。如果Application不存在,會調(diào)用LoadedApk.makeApplication創(chuàng)建一個新的Application對象。之后進入Loop循環(huán)。(執(zhí)行在新創(chuàng)建的app進程)

ActivityThread.main

ActivityThread.attach(false) //聲明不是系統(tǒng)進程

ActivityManagerProxy.attachApplication

第六階段:處理新的應(yīng)用進程發(fā)出的創(chuàng)建進程完成的通信請求,并通知新應(yīng)用程序進程啟動目標(biāo)Activity組件(執(zhí)行在AMS進程)

ActivityManagerService.attachApplication //AMS綁定本地ApplicationThread對象,后續(xù)通過ApplicationThreadProxy來通信。

ActivityManagerService.attachApplicationLocked

ActivityStack.realStartActivityLocked //真正要啟動Activity了!

ApplicationThreadProxy.scheduleLaunchActivity //AMS通過ATP通知app進程啟動Activity

第七階段:加載MainActivity類,調(diào)用onCreate聲明周期方法(執(zhí)行在新啟動的app進程)

ApplicationThread.scheduleLaunchActivity //ApplicationThread發(fā)消息給AT

ActivityThread.queueOrSendMessage

H.handleMessage //AT的Handler來處理接收到的LAUNCH_ACTIVITY的消息

ActivityThread.handleLaunchActivity

ActivityThread.performLaunchActivity

Instrumentation.newActivity //調(diào)用Instrumentation類來新建一個Activity對象

Instrumentation.callActivityOnCreate

MainActivity.onCreate

ActivityThread.handleResumeActivity

AMP.activityResumed

AMS.activityResumed(AMS進程)

一:開始請求執(zhí)行啟動Activity

MyActivity.startActivity()?

Activity.startActivity()?

Activity.startActivityForResult?

Instrumentation.execStartActivty?

ActivityManagerNative.getDefault().startActivityAsUser()?

二:ActivityManagerService接收啟動Activity的請求

ActivityManagerService.startActivity()?

ActvityiManagerService.startActivityAsUser()?

ActivityStackSupervisor.startActivityMayWait()?

ActivityStackSupervisor.startActivityLocked()?

ActivityStackSupervisor.startActivityUncheckedLocked()?

ActivityStackSupervisor.startActivityLocked()?

ActivityStackSupervisor.resumeTopActivitiesLocked()?

ActivityStackSupervisor.resumeTopActivityInnerLocked()?

三:執(zhí)行棧頂Activity的onPause方法

ActivityStack.startPausingLocked()?

IApplicationThread.schudulePauseActivity()?

ActivityThread.sendMessage()?

ActivityThread.H.sendMessage();?

ActivityThread.H.handleMessage()?

ActivityThread.handlePauseActivity()?

ActivityThread.performPauseActivity()?

Activity.performPause()?

Activity.onPause()?

ActivityManagerNative.getDefault().activityPaused(token)?

ActivityManagerService.activityPaused()?

ActivityStack.activityPausedLocked()?

ActivityStack.completePauseLocked()?

ActivityStack.resumeTopActivitiesLocked()?

ActivityStack.resumeTopActivityLocked()?

ActivityStack.resumeTopActivityInnerLocked()?

ActivityStack.startSpecificActivityLocked?

四:啟動Activity所屬的應(yīng)用進程

關(guān)于如何啟動應(yīng)用進程,前面的一篇文章已經(jīng)做了介紹,可參考:?android源碼解析之(十一)–>應(yīng)用進程啟動流程?這里在簡單的介紹一下

ActivityManagerService.startProcessLocked()?

Process.start()?

ActivityThread.main()?

ActivityThread.attach()?

ActivityManagerNative.getDefault().attachApplication()?

ActivityManagerService.attachApplication()?

五:執(zhí)行啟動Acitivity

ActivityStackSupervisor.attachApplicationLocked()?

ActivityStackSupervisor.realStartActivityLocked()?

IApplicationThread.scheduleLauncherActivity()?

ActivityThread.sendMessage()?

ActivityThread.H.sendMessage()?

ActivityThread.H.handleMessage()?

ActivityThread.handleLauncherActivity()?

ActivityThread.performLauncherActivity()?

Instrumentation.callActivityOnCreate()?

Activity.onCreate()?

ActivityThread.handleResumeActivity()?

ActivityThread.performResumeActivity()?

Activity.performResume()?

Instrumentation.callActivityOnResume()?

Activity.onResume()?

ActivityManagerNative.getDefault().activityResumed(token)?

六:棧頂Activity執(zhí)行onStop方法

Looper.myQueue().addIdleHandler(new Idler())?

Idler.queueIdle()?

ActivityManagerNative.getDefault().activityIdle()?

ActivityManagerService.activityIdle()?

ActivityStackSupervisor.activityIdleInternalLocked()?

ActivityStack.stopActivityLocked()?

IApplicationThread.scheduleStopActivity()?

ActivityThread.scheduleStopActivity()?

ActivityThread.sendMessage()?

ActivityThread.H.sendMessage()?

ActivityThread.H.handleMessage()?

ActivityThread.handleStopActivity()?

ActivityThread.performStopActivityInner()?

ActivityThread.callCallActivityOnSaveInstanceState()?

Instrumentation.callActivityOnSaveInstanceState()?

Activity.performSaveInstanceState()?

Activity.onSaveInstanceState()?

Activity.performStop()?

Instrumentation.callActivityOnStop()?

Activity.onStop()?

總結(jié):

Activity的啟動流程一般是通過調(diào)用startActivity或者是startActivityForResult來開始的startActivity內(nèi)部也是通過調(diào)用startActivityForResult來啟動Activity,只不過傳遞的requestCode小于0

Activity的啟動流程涉及到多個進程之間的通訊這里主要是ActivityThread與ActivityManagerService之間的通訊

ActivityThread向ActivityManagerService傳遞進程間消息通過ActivityManagerNative,ActivityManagerService向ActivityThread進程間傳遞消息通過IApplicationThread。

ActivityManagerService接收到應(yīng)用進程創(chuàng)建Activity的請求之后會執(zhí)行初始化操作,解析啟動模式,保存請求信息等一系列操作。

ActivityManagerService保存完請求信息之后會將當(dāng)前系統(tǒng)棧頂?shù)腁ctivity執(zhí)行onPause操作,并且IApplication進程間通訊告訴應(yīng)用程序繼承執(zhí)行當(dāng)前棧頂?shù)腁ctivity的onPause方法;

ActivityThread接收到SystemServer的消息之后會統(tǒng)一交個自身定義的Handler對象處理分發(fā);

ActivityThread執(zhí)行完棧頂?shù)腁ctivity的onPause方法之后會通過ActivityManagerNative執(zhí)行進程間通訊告訴ActivityManagerService,棧頂Actiity已經(jīng)執(zhí)行完成onPause方法,繼續(xù)執(zhí)行后續(xù)操作;

ActivityManagerService會繼續(xù)執(zhí)行啟動Activity的邏輯,這時候會判斷需要啟動的Activity所屬的應(yīng)用進程是否已經(jīng)啟動,若沒有啟動則首先會啟動這個Activity的應(yīng)用程序進程;

ActivityManagerService會通過socket與Zygote繼承通訊,并告知Zygote進程fork出一個新的應(yīng)用程序進程,然后執(zhí)行ActivityThread的mani方法;

在ActivityThead.main方法中執(zhí)行初始化操作,初始化主線程異步消息,然后通知ActivityManagerService執(zhí)行進程初始化操作;

ActivityManagerService會在執(zhí)行初始化操作的同時檢測當(dāng)前進程是否有需要創(chuàng)建的Activity對象,若有的話,則執(zhí)行創(chuàng)建操作;

ActivityManagerService將執(zhí)行創(chuàng)建Activity的通知告知ActivityThread,然后通過反射機制創(chuàng)建出Activity對象,并執(zhí)行Activity的onCreate方法,onStart方法,onResume方法;

ActivityThread執(zhí)行完成onResume方法之后告知ActivityManagerService onResume執(zhí)行完成,開始執(zhí)行棧頂Activity的onStop方法;

ActivityManagerService開始執(zhí)行棧頂?shù)膐nStop方法并告知ActivityThread;

ActivityThread執(zhí)行真正的onStop方法;

啟動流程進程間簡單分析:

Zygote進程 –> SystemServer進程 –>?各種系統(tǒng)服務(wù) –>?應(yīng)用進程?

在Actvity啟動過程中,其實是應(yīng)用進程與SystemServer進程相互配合啟動Activity的過程,其中應(yīng)用進程主要用于執(zhí)行具體的Activity的啟動過程,回調(diào)生命周期方法等操作,而SystemServer進程則主要是調(diào)用其中的各種服務(wù),將Activity保存在棧中,協(xié)調(diào)各種系統(tǒng)資源等操作。

通過ActivityManagerNative –> ActivityManagerService實現(xiàn)了應(yīng)用進程與SystemServer進程的通訊?

通過AppicationThread <–?IApplicationThread實現(xiàn)了SystemServer進程與應(yīng)用進程的通訊

ActivityManagerProxy相當(dāng)于Proxy

ActivityManagerNative就相當(dāng)于Stub

ActivityManagerService是ActivityManagerNative的具體實現(xiàn),換句話說,就是AMS才是服務(wù)端的具體實現(xiàn)!

ApplicationThreadProxy相當(dāng)于Proxy

ApplicationThreadNative相當(dāng)于Stub

ApplicationThread相當(dāng)于服務(wù)器端,代碼真正的實現(xiàn)者!

點擊桌面App圖標(biāo),Launcher進程采用Binder IPC向system_server進程發(fā)起startActivity請求;

system_server進程接收到請求后,向zygote進程發(fā)送創(chuàng)建進程的請求;

Zygote進程fork出新的子進程,即App進程;

App進程,通過Binder IPC向sytem_server進程發(fā)起attachApplication請求;

system_server進程在收到請求后,進行一系列準(zhǔn)備工作后,再通過binder IPC向App進程發(fā)送scheduleLaunchActivity請求;

App進程的binder線程(ApplicationThread)在收到請求后,通過handler向主線程發(fā)送LAUNCH_ACTIVITY消息;

主線程在收到Message后,通過發(fā)射機制創(chuàng)建目標(biāo)Activity,并回調(diào)Activity.onCreate()等方法。

到此,App便正式啟動,開始進入Activity生命周期,執(zhí)行完onCreate/onStart/onResume方法,UI渲染結(jié)束后便可以看到App的主界面。

Launch Mode

先來說說在ActivityInfo.java中定義了4類Launch Mode:

LAUNCH_MULTIPLE(standard):最常見的情形,每次啟動Activity都是創(chuàng)建新的Activity;

LAUNCH_SINGLE_TOP: 當(dāng)Task頂部存在同一個Activity則不再重新創(chuàng)建;其余情況同上;

LAUNCH_SINGLE_TASK:當(dāng)Task棧存在同一個Activity(不在task頂部),則不重新創(chuàng)建,而移除該Activity上面其他的Activity;其余情況同上;

LAUNCH_SINGLE_INSTANCE:每個Task只有一個Activity.

再來說說幾個常見的flag含義:

FLAG_ACTIVITY_NEW_TASK:將Activity放入一個新啟動的Task;

FLAG_ACTIVITY_CLEAR_TASK:啟動Activity時,將目標(biāo)Activity關(guān)聯(lián)的Task清除,再啟動新Task,將該Activity放入該Task。該flags跟FLAG_ACTIVITY_NEW_TASK配合使用。

FLAG_ACTIVITY_CLEAR_TOP:啟動非棧頂Activity時,先清除該Activity之上的Activity。例如Task已有A、B、C3個Activity,啟動A,則清除B,C。類似于SingleTop。

最后再說說:設(shè)置FLAG_ACTIVITY_NEW_TASK的幾個情況:

調(diào)用者并不是Activity context;

調(diào)用者activity帶有single instance;

目標(biāo)activity帶有single instance或者single task;

調(diào)用者處于finishing狀態(tài);

1、新的Activity類是通過類加載器方式即通過反射的方式生成的,我們可以看一下mInstrumentation.newActivity()方法:

public Activity newActivity(ClassLoader cl, String className, Intent intent)

????????????throws InstantiationException, IllegalAccessException, ClassNotFoundException {

????return (Activity)cl.loadClass(className).newInstance();

}

最后調(diào)用mInstrumentation.callActivityOnCreate()

2、在mInstrumentation.callActivityOnStart(this)方法里面就會顯式調(diào)用Activtiy的onStart()方法!

到這里我們也可以基本解決第二個問題:Activity的生命周期方法是通過Instrumentation類調(diào)用callActivityOnXXX方法最終調(diào)用Activity的onCreate等方法,調(diào)用時機為ActivityThread#performLaunchActivitiy()方法中。

3、ActivityThread#performResumeActivity()

? --> Activity#performResume()

? ? --> Instrumentation#callActivityOnResume()

? ? ? --> Activity#onResume()

另外,觀察執(zhí)行handleResumeActivity()之后的代碼,會發(fā)現(xiàn)程序會開始獲取DecorView,執(zhí)行addView()方法,里面最終會調(diào)用到ViewRootImpl#performTraversals(),即開始繪制view界面!

這里我們就解決了第三個問題:界面的繪制是在執(zhí)行Activity#onResume()之后!

4、ActivityThread的main方法是在生成一個新的app進程過程中調(diào)用的,具體是通過與Zygote通信,之后通過RuntimeInit類采用反射的方式調(diào)用ActivityThread#main()方法,即生成app中的主線程(UI線程)!

可以關(guān)注我的公眾號:Android架構(gòu)師成長之路

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容