背景
Android應用的啟動過程是一個繞不開的問題,不但對於我們開發有幫助,而且從作業系統的角度看問題,提高我們的技術視野。
第一個階段:系統啟動
1.首先是Android系統啟動.
這時候第一程式是zygote。zygote英文是受精軟的意思(一查嚇一跳)。為啥是受精軟呢?因為系統的所有程式都是由zygote程式fork而來。zygote最先啟動的第一個程式是鼎鼎大名的SystemServer程式。這個程式包含了我們常說的三個大神級系統服務,分別是ActivityManagerService,WindowManagerService以及PackegeManagerService。
2.緊接著是我們的所在應用的程式啟動。
程式入口在ActivityThread這個類的main()方法,這個main方法類似C語言的mian方法,是一個程式入口。 main方法做了以下幾件事: <1初始化我們的mainLopper和mainHander,這樣UI執行緒訊息機制就開啟了。 <2呼叫ActivityThread的attach()方法。
第二個階段:app註冊
3.ActivityThread的attach()方法
這個方法會接著呼叫ActivityManagerNatvie(一個單例類,可以獲取ActivityManagerService的例項)的getDeafault()返回ActivityManagerService例項,接著呼叫ActivityManagerService.attachApplication(mAPPThread)方法。這個mAPPThread是ApplicationThread的例項。
ApplicationThread
ApplicationThread是ActivityThread的內部類,他是App和系統跨程式互動的入口,它的實現類在客戶端程式,SystemServer的AMS通過ApplicationThread的例項來和App程式通訊,包括生命週期的回撥。ApplicationThread在App程式的實現類通過H這個handler和ActivityThread跨執行緒互動,完成生命週期的最終回撥,這些時間型別是諸如:LAUNCH_ACTIVITY和RESUME_ACTIVITY以及Servivce的生命週期也是H這個Handler處理的,這個叫做H的Handler是UI執行緒。
Servivce為什麼是在UI執行緒?
這個問題上一段已經回答,因為生命週期的回撥的H這個Handler是在UI執行緒。
4.ActivityManagerService.attachApplication(mAPPThread)方法
補充一下: 系統看來,其實也就是AMS看來,每個App都對應一個程式,儲存在ProcessRecord這個資料結構。app的每個Activity都對用一個ActivityRecord這個資料結構,每個Activity都對應一個Token,這個Token也是Binder物件,用來唯一都應一個Activity。
5.呼叫mAPPThread.bindApplication(ProcessRecord等引數)
這是一個跨程式呼叫實際上把App資訊同步到ProcessRecord方便系統管理。
6.ActivityStackSupervisor.attachApplicationLocked(ProcessRecord)方法
這個類是一個AMS的一個棧管理類,裡面儲存著ActivityStack的集合。在這個方法,會遍歷各個ActivityStack,找到前臺棧,找到裡面的TopActivity。然後比較 傳進來的ProcessRecord.processName和UID是否個和opActivity對用的ActivityRecord裡面的一致。如果一致,就呼叫ActivityStackSupervisor.realStartAcvitiyLocked(ProcessRecord,ActivityRecord)方法。
7.ActivityStackSupervisor.realStartAcvitiyLocked(ProcessRecord,ActivityRecord)方法。
這個方法會呼叫傳過來的ApplicationThread例項的ScheduelLaunchActivity(包括ActivityRecord)方法。
第三個階段:啟動第一個Activity
8.ApplicationThread.ScheduelLaunchActivity(包括ActivityRecord)方法。
這個方法是跨程式的,會把ActivityRecord同步到App程式的ActivityRecordClient資料結構,用來後面構造Application和Activity等。
9.傳送給H一個H.LAUNCH_ACTIVITY的訊息
10.呼叫ActivityThread的HandleLaunchActivity()方法。
接著呼叫PerformLaunchActivity方法和HandleLaunchActivtiy()方法。 #第四個階段:顯示畫面 這個階段後續再詳細講,這裡就簡單提一下。
PerformLaunchActivity做的事
1.這個方法主要是構造Application和通過mInstrumention.newActivity()構造Activity。 2.呼叫Activity的attach(application的ContextImpl等資訊)
Activity的attach(application的ContextImpl等資訊)
這個方法會初始化一個Window,以後詳細講,人格檢視都是附在一個window的docorView上,然後由WMS.addView顯示。
HandleLaunchActivtiy
這個方法會呼叫Actiity的resume()方法,並且在makrVisible()裡面呼叫WMS.addView(window),這個windows裡面的docorView的contentView就是onCreate()裡面setContentView(int layout)設定的contentView。
最後顯示出來了
注意關於WMS.addView(window),這個系統服務,我們下次再講,裡面有一個類RootViewImpl,這個類負責管理我們contentView檢視樹的逐級繪製。