本部份內容是關於Android進階的一些知識總結,涉及到的知識點比較雜,不過都 是面試中幾乎常問的知識點,也是加分的點。 關於這部份內容,可能須要有一些具體的項目實踐。在面試的過程當中,結合具體自 身實踐經歷,才能更加深刻透徹的描繪出來。java
(年前有不少加我,今天才一一回復,發現不少都失效了,須要的能夠從新加一次)
(順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)android
① 點擊桌面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的主界面。
上面的一些列步驟簡單介紹了一個APP啓動到主頁面顯示的過程,可能這些流程中 的一些術語看的有些懵,什麼是Launcher,什麼是zygote,什麼是 applicationThread
..... 下面咱們一一介紹。git
zygote意爲「受精卵「。Android是基於Linux系統的,而在Linux中,全部的進程都是 由init進程直接或者是間接fork出來的,zygote進程也不例外。github
在Android系統裏面,zygote是一個進程的名字。Android是基於Linux System的, 當你的手機開機的時候,Linux的內核加載完成以後就會啓動一個叫「init「的進程。在 Linux System裏面,全部的進程都是由init進程fork出來的,咱們的zygote進程也不 例外面試
咱們都知道,每個App其實都是瀏覽器
因此當系統裏面的第一個zygote進程運行以後,在這以後再開啓App,就至關於開 啓一個新的進程。而爲了實現資源共用和更快的啓動速度,Android系統開啓新進 程的方式,是經過fork第一個zygote進程實現的。因此說,除了第一個zygote進 程,其餘應用所在的進程都是zygote的子進程,這下你明白爲何這個進程叫「受精 卵」了吧?由於就像是一個受精卵同樣,它能快速的分裂,而且產生遺傳物質同樣的 細胞!服務器
SystemServer
也是一個進程,並且是由zygote進程fork出來的。架構
知道了SystemServer
的本質,咱們對它就不算太陌生了,這個進程是Android Framework裏面兩大很是重要的進程之一——另一個進程就是上面的zygote進 程。app
爲何說SystemServer
很是重要呢?由於系統裏面重要的服務都是在這個進程裏面 開啓的,好比 ActivityManagerService
、PackageManagerService
、 WindowManagerService
等等。框架
ActivityManagerService
,簡稱AMS,服務端對象,負責系統中全部Activity的生命 週期。 ActivityManagerService
進行初始化的時機很明確,就是在SystemServer
進程開啓 的時候,就會初始化ActivityManagerService
。
下面介紹下Android系統裏面的服務器和客戶端的概 念。
其實服務器客戶端的概念不只僅存在於Web開發中,在Android的框架設計中,使 用的也是這一種模式。服務器端指的就是全部App共用的系統服務,好比咱們這裏 提到的ActivityManagerService
,和前面提到的PackageManagerService
、 WindowManagerService
等等,這些基礎的系統服務是被全部的App公用的,當某 個App想實現某個操做的時候,要告訴這些系統服務,好比你想打開一個App,那 麼咱們知道了包名和MainActivity
類名以後就能夠打開
Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); ComponentName cn = new ComponentName(packageName, className); intent.setComponent(cn); startActivity(intent);
可是,咱們的App經過調用startActivity()
並不能直接打開另一個App,這個方法會 經過一系列的調用,最後仍是告訴AMS說:「我要打開這個App,我知道他的住址和 名字,你幫我打開吧!」因此是AMS來通知zygote進程來fork一個新進程,來開啓我 們的目標App的。這就像是瀏覽器想要打開一個超連接同樣,瀏覽器把網頁地址發 送給服務器,而後仍是服務器把須要的資源文件發送給客戶端的。
知道了Android Framework的客戶端服務器架構以後,咱們還須要瞭解一件事情, 那就是咱們的App和AMS
(SystemServer
進程)還有zygote進程分屬於三個獨立的進 程,他們之間如何通訊呢?
App與AMS
經過Binder進行IPC
通訊,AMS
(SystemServer
進程)與zygote經過 Socket進行IPC
通訊。後面具體介紹。
那麼AMS
有什麼用呢?在前面咱們知道了,若是想打開一個App的話,須要AMS
去 通知zygote進程,除此以外,其實全部的Activity的開啓、暫停、關閉都須要AMS
來控制,因此咱們說,AMS
負責系統中全部Activity的生命週期。 在Android系統中,任何一個Activity的啓動都是由AMS
和應用程序進程(主要是 ActivityThread
)相互配合來完成的。AMS
服務統一調度系統中全部進程的 Activity啓動,而每一個Activity的啓動過程則由其所屬的進程具體來完成。
當咱們點擊手機桌面上的圖標的時候,App就由Launcher開始啓動了。可是,你有 沒有思考過Launcher究竟是一個什麼東西? Launcher本質上也是一個應用程序,和咱們的App同樣,也是繼承自Activity packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
public final class Launcher extends Activity implements View.OnClickListener, OnLongClickListener, La uncherModel.Callbacks, View.OnTouchListener { }
Launcher實現了點擊、長按等回調接口,來接收用戶的輸入。既然是普通的App, 那麼咱們的開發經驗在這裏就仍然適用,好比,咱們點擊圖標的時候,是怎麼開啓 的應用呢?捕捉圖標點擊事件,而後startActivity()
發送對應的Intent請求唄!是的,Launcher也是這麼作的,就是這麼easy!
每一個Activity都持有Instrumentation
對象的一個引用,可是整個進程只會存在一個 Instrumentation
對象。 Instrumentation
這個類裏面的方法大多數和Application
和 Activity
有關,這個類就是完成對Application
和Activity
初始化和生命週期的工具 類。Instrumentation
這個類很重要,對Activity生命週期方法的調用根本就離不開 他,他能夠說是一個大管家。
ActivityThread
,依賴於UI線程。App和AMS
是經過Binder傳遞信息的,那麼 ActivityThread
就是專門與AMS
的外交工做的。
前面咱們已經知道了App的啓動以及Activity的顯示都須要AMS
的控制,那麼咱們便 須要和服務端的溝通,而這個溝通是雙向的。
客戶端-->服務端
並且因爲繼承了一樣的公共接口類,ActivityManagerProxy
提供了與 ActivityManagerService
同樣的函數原型,使用戶感受不出Server是運行在本地仍是 遠端,從而能夠更加方便的調用這些重要的系統服務。
服務端-->客戶端
仍是經過Binder通訊,不過是換了另一對,換成了ApplicationThread
和 ApplicationThreadProxy
。
他們也都實現了相同的接口IApplicationThread
private class ApplicationThread extends ApplicationThreadNative { } public abstract class ApplicationThreadNative extends Binder i mplements IApplicationThread{ } class ApplicationThreadProxy implements IApplicationThread { }
好了,前面羅裏吧嗦的一大堆,介紹了一堆名詞,可能不太清楚,不要緊,下面結 合流程圖介紹。
① 先從Launcher的startActivity()
方法,經過Binder通訊,調用ActivityManagerService
的startActivity
方法。
② 一系列折騰,最後調用startProcessLocked()
方法來建立新的進程。
③ 該方法會經過前面講到的socket通道傳遞參數給Zygote進程。Zygote孵化自身。 調用ZygoteInit.main()
方法來實例化ActivityThread
對象並最終返回新進程的pid。
④ 調用ActivityThread.main()
方法,ActivityThread
隨後依次調用Looper.prepareLoop()
和Looper.loop()
來開啓消息循環。
方法調用流程圖以下:
更直白的流程解釋:
①App發起進程:
當從桌面啓動應用,則發起進程即是Launcher所在進程;當從某 App內啓動遠程進程,則發送進程即是該App所在進程。發起進程先經過binder發送 消息給system_server
進程;
②system_server進程:
調用Process.start()
方法,經過socket向zygote進程發送創 建新進程的請求;
③zygote進程:
在執行ZygoteInit.main()
後便進入runSelectLoop()
循環體內,當有 客戶端鏈接時便會執行ZygoteConnection.runOnce()
方法,再通過層層調用後fork 出新的應用進程;
④新進程:
執行handleChildProc
方法,最後調用ActivityThread.main()
方法。
上面建立進程後,執行ActivityThread.main()
方法,隨後調用attach()方法。
將進程和指定的Application
綁定起來。這個是經過上節的ActivityThread
對象中調用 bindApplication()
方法完成的。該方法發送一個BIND_APPLICATION
的消息到消息 隊列中, 最終經過handleBindApplication()
方法處理該消息. 而後調用 makeApplication()
方法來加載App的classes到內存中。
方法調用流程圖以下:
更直白的流程解釋:
(若是看不懂AMS,ATP等名詞,後面有解釋)
通過前兩個步驟以後, 系統已經擁有了該application
的進程。 後面的調用順序就是 普通的從一個已經存在的進程中啓動一個新進程的activity了。
實際調用方法是realStartActivity()
, 它會調用application線程對象中的 scheduleLaunchActivity()
發送一個LAUNCH_ACTIVITY
消息到消息隊列中, 經過 handleLaunchActivity()
來處理該消息。在 handleLaunchActivity()
經過 performLaunchActiivty()
方法回調Activity的onCreate()
方法和onStart()
方法,而後通 過handleResumeActivity()
方法,回調Activity的onResume()
方法,最終顯示Activity 界面。
更直白的流程解釋:
簡稱:
ATP: ApplicationThreadProxy
AT: ApplicationThread
AMP: ActivityManagerProxy
AMS: ActivityManagerService
圖解:
① system_server進程中調用startProcessLocked
方法,該方法最終經過socket方式, 將須要建立新進程的消息告知Zygote進程,並阻塞等待Socket返回新建立進程的pid;
② Zygote進程接收到system_server發送過來的消息, 則經過fork的方法,將zygote 自身進程複製生成新的進程,並將ActivityThread
相關的資源加載到新進程app process,這個進程多是用於承載activity等組件;
③ 在新進程app process向servicemanager
查詢system_server進程中binder服務端 AMS, 獲取相對應的Client端,也就是AMP. 有了這一對binder c/s對, 那麼app process即可以經過binder向跨進程system_server發送請求,即attachApplication()
④system_server
進程接收到相應binder操做後,通過屢次調用,利用ATP向app process
發送binder請求, 即bindApplication. system_server
擁有ATP/AMS, 每個 新建立的進程都會有一個相應的AT/AMP,從而能夠跨進程 進行相互通訊. 這即是進 程建立過程的完整生態鏈。
以上大概介紹了一個APP從啓動到主頁面顯示經歷的流程,主要從宏觀角度介紹了 其過程,具體可結合源碼理解。
(順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)
感謝支持~