Activity啓動流程(源碼分析)

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/qq_28029345/article/details/64123960

activity作爲android四大組件之一,也是android app中最爲重要的一個部分,很多時候我們開啓一個activity 只需調用startActivity即可,卻不知背後系統爲我們做了哪些事。而這個流程可以說相當複雜,其中進行了多次進程間通信,下面我們來分析一下。


1,首先在actvity中調用startActivity(Intent intent); Intent作爲意圖對象,就相當於一個路由地址一樣,我們要選擇哪個activity,向這個activity傳遞什麼樣的數據,都是通過Intent來決定的。

2,在activity源碼中,我們發現startActivity 緊接着調用的是startActivityForResult(),在startActivityForResult中,又通過Instrumentation,它只是一個單純的類,並且它是activity的直接操作者,activity的生命週期都是通過Instrumentation這個類來處理的,但他並不是控制者.

3,Instrumentation調用execStartActivity,這個方法還未跨進程調用,而在方法中獲取到一個服務類(ActivityManagerNative.getDefault(),這個服務類是怎麼拿到的呢?其實在我們app運行時這個服務類已經被裝進ActivityManagerNative裏了,它是一個靜態類,從代碼中可以看到ServiceManager.getService("activity"),其實這個服務類就是在整個android系統中至關重要的ActivityManagerService(AMS),而AMS本身就是一個binder接口,所以我們拿到的是一個AMS的分身,我們通過AMS分身調用startActivity(),至於爲什麼是分身,那就是AIDL原理的知識了.

4.我們通過Ams調用startActivity,走到這裏其實已經是在跨進程通信了,Ams是運行在systemServer進程中的,而我們app中startActivity是運行在我們應用程序進程中的,所以ams調用startActivity後,就進入了Ams這個類,ams類調用startActivity()->startActivityAsUser()然後又交給了(ASP) mStackSupervisor.startActivityMayWait();

5.ActivityStackSupervisor(ASP)是個什麼東西?通過源碼獲知,它管理了整個activity的任務棧,android中會有不同app,不同app默認又運行在不同的棧中,爲什麼由它來管理呢?如果我們app本身就能管理棧,那不同棧之間豈不是要互相通信,很顯然app之間通信會造成不安全,所以ams通過mStackSupervisor來管理所有app的任務棧,app沒有管理的權限。 緊接着我們調用ASP的startActivityMayWait(),這裏邊就是根據Intent去找出相對應的activity信息.

6.ASP去拿到PageManagerService的binder分身去解析Intent,得到符合條件的Acticitys,pms與ams同屬systemServer進程, 在這裏還是透過binder通信,說明binder在android中無處不在。接着ASP調用startActivityLocked(),在這個方法中進行了Intent驗證,權限的檢測等,然後調用startActivityUncheckedLocked(),這個方法檢測activity啓動模式,根據啓動模式分配或者創建任務棧ActivityStack,而這個ActivityStack即Activity的直接管理對象,接着通過ActivityStack調用startActivityLocked();

7.ActivityStack調用startActivityLocked其實這個方法裏並沒有找到開啓新activity的代碼,而是去查找要要pause掉的activity,通過函數resumeTopActivityLocked(),然後調用startPausingLocked方法

8.startPausingLocked調用ApplicationThread(它也是一個binder分身)拿到要pause的那個activity所在進程ApplicationThread執行shedulePauseActivity()方法,又是一輪跨進程通信。而ApplicationThread是ActivityThread的內部類,ApplicationThread向消息隊列裏發了條消息.ActivityThread收到後調用自身的handlePauseActivity方法

9.接着handlePauseActivity方法中除了管理那個被pause的Activity的同時又與ams做了一個跨進程通信來告訴ams我已經pause了,所以調用ams的ActivityPaused方法

10.ams收到activity被pause的消息,然後調用activityStack的activityPauseLocked方法,然後有ASP去執行了resumeTopActivitiesLocked();

11.Asp在resumeTopActivitiesLocked方法中去判斷app進程是不是已經存在了,如果不存在他就與另一個進程通信,那就是孵化器進程,而與孵化器進程通信的方式並不是採用binder方式,而是直接用socket通信,讓其複製一個進程出來,調用startProccessLocked()

12.在app進程已經存在的情況下則調用startSecificActivityLocked()方法緊接着又是跨進程通知app進程執行scheduleLaunchActivity->交由Instrumentation創建activity並執行onCreate函數.

總結:以上我們看到一個activity啓動流程如此複雜,但是分析源碼還是能摸清套路的,這種架構就是典型的C/S架構,我們所看到的activity只是最淺顯的東西,而其實activity的真身並不在我們app內,而是由AMS直接管理並操控着,所以google沒有給app開發人員任何控制點,裏邊環環相扣,形成一張巨網。


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