1. 程式人生 > >Activity啟動流程詳解

Activity啟動流程詳解

image.png
image.png
看到上面的標記A:
image.png

看到標記C處,這個IApplicationThread是什麼呢?這個我在Activity生命週期回撥是如何被回撥的?有解釋過,這裡我簡單的解釋一下:這個IApplicationThread是Android應用程式提供對外(即系統ActivityManagerService)提供服務,外部可以持有這個類的proxy來和我的Android應用程式跨程序通訊。
接著看到標記D處:
這裡呼叫了ActivityManager.getService如下:

這裡通過ServiceManger獲取到了系統服務ActivityManager的代理物件,這個am實際上是一個proxy。
回到標記D的後半截startActivity如下:
image.png

image.png
上圖提到會導致這個onTransact被呼叫,那麼我們首先要找到AM,這個AM在哪裡呢,這個AM一定是繼承了Stub的,如下:
image.png

image.png
分析到上圖位置,可以看到應用程式要求啟動一個新的Activity,然後系統服務ActivityManagerService接收到這個要求,呼叫它自身的startActivity方法:

看到上圖示記G處:
image.png

接著看到標記H:

快受不了啦,還在兜兜轉轉,抓狂呀,堅持下,看到上圖的標記 I :
image.png
image.png
看到上文標記K:
image.png
接著跟進上圖示記M:

進入N:

進入O:
image.png
進入P:
image.png
進入Q:
image.png
看到上圖說的,scheduleLaunchActivity被呼叫之後,應用程式的真正的這個提供 遠端服務物件的這個方法也會被呼叫,那麼在應用程式中這個物件在哪裡被複制呢?關於這一點我在

Activity生命週期回撥是如何被回撥的?有提到過,其實是在ActivityThread中賦值的:
image.png
這裡我在強調一下ApplicationThread的作用:
為什麼要有ApplicationThread呢?首先Android應用程式可以通過ActivityManager提供給我們的代理類來向系統ActivityManagerService傳送資訊比如Android應用程式傳送資訊給系統服務ActivityManagerService
要求啟動一個Activity,換句話說Android應用程式持有ActivityManager的代理物件就可以像系統服務ActivityManagerService發訊息,那反過來系統服務ActivityManager要嚮應用程式傳送訊息應該怎麼辦?一樣的道理系統服務只要持有Android應用程式提供的一個代理物件不就可以了嗎?所以這個ApplicationThread物件的意義就在於此。

繼續:
image.png

image.png

image.png

image.png
看到V1:
image.png

image.png

上圖分析完之後,Activity的onCreate onstart也呼叫完了,來到V2:


接著看到W1:
image.png
image.png
image.png
再回到W2

image.png

到此Activity的整個啟動流程都分析完了,回顧上文分析,Activity的啟動流程還是比較複雜的,總結來講應該重點把握整個流程中,里程碑式的幾個事件:

  • Binde機制,Stub代表什麼,proxy代表什麼
  • ApplicationThread的作用以及在哪裡被賦值的
  • H是什麼
  • ViewRootImpl 以及 DecorView,View繪製流程

如果你熟悉AIDL的話,你會知道生成的程式碼的Stub表示的對外提供的遠端服務,Proxy則表示這個遠端服務物件的代理。
ApplicationThread是android應用程式對外或者說對系統服務ActivityManagerService提供的遠端服務,系統服務ActivityManagerService要想控制我的Android應用程式可以通過這個物件的代理物件,反過來android應用程式也是通過ActivityManager的代理物件來向系統服務傳遞訊息的,所以以上覆雜兜兜轉轉的啟動流程可以通過以下一張圖來極簡的描述:
image.png

H是一個Handler型別,先後會建立一個Activity物件,並關聯上Context,Window,然後回撥oncreat、onstart、之後再來到onResume,onResume這一步要做的東西比較多,這個時候onCreat已經被呼叫了,所以SetContentView也建立好了,onReSume這一步則是要把這些View繪製出來,首先建立了ViewRootImpl ,然後呼叫viewRootImpl的setView方法將DecorView設定進ViewRootImpl,這個方法之後View的繪製流程就即將開啟了。

總結

Activity啟動流程是面試中常問的問題,我認為在回答的時候最好能將我上面提到的幾個“里程碑事件”有機的組合在一起描述 回到,反而那些函式跳來跳去的兜兜轉轉並不重要,也不太可能記得住,記住核心的東西本質的東西才最重要。