App與Activity啓動時序

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/u012267215/article/details/91406211
 

 

 


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

app進程通過ActivityManager.getService (高版本)或者 ActivityManagerNative.getDefault(低版本)返回的IActivityManager來調用系統進程AMS中的方法。該IActivityManager是AMS在app進程的binder代理對象
同樣,系統進程通過ProcessRecord.IApplicationThread調用app進程相關方法。IApplicationThread是系統進程持有的app進程中ApplicationThread的Binder代理對象。
AMS通過binder代理調用到ApplicationThread(ActivityThread的內部類)中的方法後,通過主線程(ActivityThread中的main方法)中開啓的handler消息輪詢來通知主線程調用相關方法。主線程的相關聲明週期方法的具體實現會委託給Instrumentation類實現,在Instrumentation類中,會調用具體組件的相關生命週期方法。
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生命週期。測試用到這個類比較多。
ActivityStackSupervisor
負責所有Activity棧的管理。內部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關的Activity棧;mFocusedStack管理的是當前顯示在前臺Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前臺Activity的Activity棧。
 


 

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

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

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

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

         說明: 該類用於具體操作某個Activity的功能----單向(oneway)調用AMS以及統計、測量該應用程序的所有開銷。

            一個Instrumentation類對應於一個進程。每個Activity內部都有一個該Instrumentation對象的引用。

 

      舉個例子吧。

           我們將我們應用程序比作一個四合院,那麼Activity對應於四合院的人,ActivithThread對應於院子的主人----管理所有人,

    Instrumentation對應於管家------受氣的命,接受來自人(Activity/ActivithThread)的命令 ,去單向(oneway)調用AMS 。
 

ApplicationThread類是ActivityThread的內部類:

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

具體流程
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進程)


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


 
一:開始請求執行啓動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() 
 

三:執行棧頂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所屬的應用進程

關於如何啓動應用進程,前面的一篇文章已經做了介紹,可參考: android源碼解析之(十一)–>應用進程啓動流程 這裏在簡單的介紹一下


ActivityManagerService.startProcessLocked() 
Process.start() 
ActivityThread.main() 
ActivityThread.attach() 
ActivityManagerNative.getDefault().attachApplication() 
ActivityManagerService.attachApplication() 

五:執行啓動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執行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() 

 

總結:

Activity的啓動流程一般是通過調用startActivity或者是startActivityForResult來開始的

startActivity內部也是通過調用startActivityForResult來啓動Activity,只不過傳遞的requestCode小於0

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

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

ActivityManagerService接收到應用進程創建Activity的請求之後會執行初始化操作,解析啓動模式,保存請求信息等一系列操作。

ActivityManagerService保存完請求信息之後會將當前系統棧頂的Activity執行onPause操作,並且IApplication進程間通訊告訴應用程序繼承執行當前棧頂的Activity的onPause方法;

ActivityThread接收到SystemServer的消息之後會統一交個自身定義的Handler對象處理分發;

ActivityThread執行完棧頂的Activity的onPause方法之後會通過ActivityManagerNative執行進程間通訊告訴ActivityManagerService,棧頂Actiity已經執行完成onPause方法,繼續執行後續操作;

ActivityManagerService會繼續執行啓動Activity的邏輯,這時候會判斷需要啓動的Activity所屬的應用進程是否已經啓動,若沒有啓動則首先會啓動這個Activity的應用程序進程;

ActivityManagerService會通過socket與Zygote繼承通訊,並告知Zygote進程fork出一個新的應用程序進程,然後執行ActivityThread的mani方法;

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

ActivityManagerService會在執行初始化操作的同時檢測當前進程是否有需要創建的Activity對象,若有的話,則執行創建操作;

ActivityManagerService將執行創建Activity的通知告知ActivityThread,然後通過反射機制創建出Activity對象,並執行Activity的onCreate方法,onStart方法,onResume方法;

ActivityThread執行完成onResume方法之後告知ActivityManagerService onResume執行完成,開始執行棧頂Activity的onStop方法;

ActivityManagerService開始執行棧頂的onStop方法並告知ActivityThread;

ActivityThread執行真正的onStop方法;


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 

啓動流程進程間簡單分析:
Zygote進程 –> SystemServer進程 –> 各種系統服務 –> 應用進程 
在Actvity啓動過程中,其實是應用進程與SystemServer進程相互配合啓動Activity的過程,其中應用進程主要用於執行具體的Activity的啓動過程,回調生命週期方法等操作,而SystemServer進程則主要是調用其中的各種服務,將Activity保存在棧中,協調各種系統資源等操作。
通過ActivityManagerNative –> ActivityManagerService實現了應用進程與SystemServer進程的通訊 
通過AppicationThread <– IApplicationThread實現了SystemServer進程與應用進程的通訊
ActivityManagerProxy相當於Proxy
ActivityManagerNative就相當於Stub
ActivityManagerService是ActivityManagerNative的具體實現,換句話說,就是AMS纔是服務端的具體實現!
ApplicationThreadProxy相當於Proxy
ApplicationThreadNative相當於Stub
ApplicationThread相當於服務器端,代碼真正的實現者!
點擊桌面App圖標,Launcher進程採用Binder IPC向system_server進程發起startActivity請求;
system_server進程接收到請求後,向zygote進程發送創建進程的請求;
Zygote進程fork出新的子進程,即App進程;
App進程,通過Binder IPC向sytem_server進程發起attachApplication請求;
system_server進程在收到請求後,進行一系列準備工作後,再通過binder IPC向App進程發送scheduleLaunchActivity請求;
App進程的binder線程(ApplicationThread)在收到請求後,通過handler向主線程發送LAUNCH_ACTIVITY消息;
主線程在收到Message後,通過發射機制創建目標Activity,並回調Activity.onCreate()等方法。
到此,App便正式啓動,開始進入Activity生命週期,執行完onCreate/onStart/onResume方法,UI渲染結束後便可以看到App的主界面。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------​​​​​​​ 

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

LAUNCH_MULTIPLE(standard):最常見的情形,每次啓動Activity都是創建新的Activity;
LAUNCH_SINGLE_TOP: 當Task頂部存在同一個Activity則不再重新創建;其餘情況同上;
LAUNCH_SINGLE_TASK:當Task棧存在同一個Activity(不在task頂部),則不重新創建,而移除該Activity上面其他的Activity;其餘情況同上;
LAUNCH_SINGLE_INSTANCE:每個Task只有一個Activity.
再來說說幾個常見的flag含義:

FLAG_ACTIVITY_NEW_TASK:將Activity放入一個新啓動的Task;
FLAG_ACTIVITY_CLEAR_TASK:啓動Activity時,將目標Activity關聯的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。
最後再說說:設置FLAG_ACTIVITY_NEW_TASK的幾個情況:

 

調用者並不是Activity context;
調用者activity帶有single instance;
目標activity帶有single instance或者single task;
調用者處於finishing狀態;

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

public Activity newActivity(ClassLoader cl, String className, Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}
最後調用mInstrumentation.callActivityOnCreate()
 

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

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

3、ActivityThread#performResumeActivity()
  --> Activity#performResume()
    --> Instrumentation#callActivityOnResume()
      --> Activity#onResume()
另外,觀察執行handleResumeActivity()之後的代碼,會發現程序會開始獲取DecorView,執行addView()方法,裏面最終會調用到ViewRootImpl#performTraversals(),即開始繪製view界面!
這裏我們就解決了第三個問題:界面的繪製是在執行Activity#onResume()之後!

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

 

內容引自如下:

https://blog.csdn.net/qinjuning/article/details/7262769

https://www.jianshu.com/p/dc6b0ead30aa

https://www.jianshu.com/p/274ccb315a7a

https://www.cnblogs.com/zl1991/p/6883517.html

https://www.cnblogs.com/ldq2016/p/6891009.html

https://blog.csdn.net/lj19851227/article/details/82562115​​​​​​​

https://www.jianshu.com/p/86ad1026cef3

 
————————————————
版權聲明:本文爲CSDN博主「彥彬」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u012267215/article/details/91406211

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章