1.概要
startActivity啟動一個activity的源碼分析,涉及概念較多,比如binder,aidl跨進程通信(ipc),棧管理概念;啟動的時序圖如下圖(來自其他blog)所示:
接下來基于sdk 23 源碼里面看看,每個流程分別做了什么。主要分為APP進程部分、Server進程部分;
2.APP進程(上)
2.1 Context,ApplicationThread(在ActivityThread里面),Instrumentation
首先啟動一個頁面,比如activity里面通過context.startActivity,會調用到startActivityForResult方法,接著會調用Instrumentation的execStartActivity方法,里面有幾個入參需要注意的,第一個context自身,一個是ApplicationThread(它是一個binder本地對象,或者說是server對象,它是抽象類ApplicationThreadNative的實現類,具體能力的承載類,為后續AMS持有它的proxy進行啟動activity使用),還有一個參數intent(傳遞參數);
2.2 ActivityManagerNative,ActivityManagerService(AMS),ActivityManagerProxy(asInterface,它入參就是從sm那里拿來的binder代理對象),ServiceManager,
ServiceManager只是一個裝飾類,最終調用的方法是binder內核驅動的方法,是通過BinderInterner里獲取的binder對象,如:addService,registerService等方法。它對應的也有serviceManagerNative等,所有的binder服務(AMS/PMS/)等都是從這邊獲取到對應client對象。
通過ActivityManagerProxy.startActivity,他的里面調用transact,接著通過binder IPC進入AMS;到此為止都是在**APP進程中**
3.Server進程
--------------------Server進程部分-------------------
該部分主要是做一些啟動前的校驗,創建和管理Activity stack ,創建進程,綁定ApplicationThreadProxy.
3.1 AMN.onTransact
接下來我們就在, AMN是個抽象類,是個System server進程里面的本地服務,onTransact方法被調用,里面是真正的StartActivity方法的實現是在AMS中。
3.2 AMS.onTransact
在里面會調用startActivityAsUser,在SDK 23中是進入ActivityStackSupervisor,24中進入ActivityStarter的startActivityMayWait。
ActivityStackSupervisor為了多屏而出現,管理多個ActivityStack
3.3 ASS.startActivityMayWait
這個方法的作用主要是獲取ActivityInfo信息(如果有多個activity會彈框讓用戶選擇),里面會經過PMS獲取ActivityInfo信息,并保存在intent對象中,接著進入startActivityLocked,它的返回值里,如果大于等于0標識啟動成功,小于零標識啟動失敗。
3.4 ASS.startActivityLocked
該方法會進行一系列的常規檢查,比如activity是否在AndroidManifest注冊,是否存在這個activity等等,常規檢查通過之后,會進行權限的檢查;如果在都成功的情況下,進行ActivityRecrd(一個Activity可以對應多個ActivityRecord)的創建;并校驗App切換是否允許,如果不允許則要啟動的Activity添加到pending中,并直接返回,相當于檢查下是否又被阻塞的activity,優先啟動。
3.5 ASS.startActivityUncheckedLocked (棧管理相關的操作)
這個階段就不需要做些權限的檢查;這個函數的主要作用就是找到或者創建新的Activity所屬于的task對象,之后調用ActivityStack的startActivityLocked。其中會根據我的ActivityRecord的屬性,從標簽中獲取,進行Standard、singleTop、singleTask、singleInstance相關要求的處理。比如是否需要新建棧,或者已有棧中是否存在此Activity,如果應用之前沒有起來過,那找不到task如何處理等等。
如果不存在該Activity,則需要創建進入
ActivityStack(棧的管理,activity是否顯示等等)
3.6 AS.startActivityLocked
入參里面,ActivityRecord,是否需要立馬顯示,是否需要創建新的task等等。
如果新啟動一個app,表示宿主棧ActivityStack中沒有歷史任務,或者強制要求在新的任務中啟動Activity, 既然是一個新任務,那么就需要需要將任務插入宿主棧頂。放入并放在棧頂之后,將Activity推入顯示狀態。
3.7 AS.resumeTopActivityLocked-> resumeTopActivityInnerLocked
找到第一個沒有finishing的棧頂activity,找不到直接回到桌面,找到了,就執行startPausingLocked暫停activity,接著進入startSpecificActivityLocked.
3.8 AS.resumeTopActivityInnerLocked
嘗試將ActivityRecord遷移到顯示狀態(Resumed),如果發現待顯示的Activity的宿主進程可能沒有啟動,則需要回到ASS.startSpecificActivityLocked。
ActivityStackSupervisor
3.9 ASS. startSpecificActivityLocked
如果通過包名,發現才宿主進程不存在,則啟動一個新的應用進程。這時候會調用AMS.newProcessRecord來創建一個新的ProcessRecord,然后再調用另外一個重載的AMS.startProcessLocked()函數,來創建一個進程。進入AMS.startProccesslocked。如果已經存在則直接進入realStartActivityLocked方法,進行啟動activity。
ActivityManagerService
3.10 AMS.startProccesslocked (參考:http://gityuan.com/2016/10/09/app-process-create-2/)
簡單就是發送一個消息,通知Zygote進程fork一個應用進程,同時會調用入口程序的ActivityThread的main方法,該方法中會初始化幾個比較的變量,如ApplicationThread,looper,H。以及非常重要的AT.attach過程,通過binder, 調用到AMP-> AMS.attachApplication, 其參數mAppThread的數據類型為ApplicationThread,將ApplicationThreadProxy綁定到AMS。
到此為止創建了待啟動的Activity的宿主應用進程.
3.11 ASS.attachApplicationLocked
宿主進程如果創建好了,則調用realStartActivityLocked啟動activity
4.APP進程(下)
--------------------回到APP進程部分-------------------
4.1 ApplicationThreadProxy.scheduleLaunchActivity
通過IPC就會回到app進程中,ApplicationThreadProxy.scheduleLaunchActivity回調ActivityThreadNative.onTransact,從而進入ApplicationThread的scheduleLaunchActivity進行真正啟動Activity
4.2 ApplicationThread. scheduleLaunchActivity
通過H (handler)sendMessage(H.LAUNCH_ACTIVITY),進入handleLaunchActivity
4.3 ApplicationThread. handleLaunchActivity
通過performLaunchActivity獲取一個Activity對象(反射等),具體如4.4,然后執行隊形的oncreate,onstart, onresume等生命周期
4.4 ApplicationThread.performLaunchActivity
該函數負責實際執行應用進程中Activity的啟動,是系統進程調度啟動一個Activity的落腳地,也就是Activity生命周期的開始地方。一個新的Activity對象,是通過反射創建的,所以需要包名、類名等信息,部分信息已經從系統進程傳遞到應用進程了,部分信息也都可以通過PackageManager再向系統進程索?。恍陆ㄒ粋€Activity對象。有了參數以后,便可以通過ClassLoader加載到Activity對應的類,反射構建之。同時Activity的Context、Theme會在Activity對象構建之后被初始化;接著就開始Actiivty的生命周期調用如onCreate,onStart
4.5 ApplicationThread.handleResumeActivity -> performResumeActivity
直至Activity處于顯示狀態。
參考:http://gityuan.com/2016/03/12/start-activity/