1. 程式人生 > >Android Framework的啟動方法及原理詳解

Android Framework的啟動方法及原理詳解

安卓系統中執行的第一個Dalvik虛擬機器叫做zygote,意思是“卵”。這“卵”還是挺有用的,因為接下來所有的Dalvik虛擬機器程序都是這個“卵”孵化出來的。

zygote程序中包含兩個主要模組,分別如下:

1、Socket服務端。用於接收啟動新的Dalvik程序的命令。

2、Framework共享類及共享資源。當zygote程序啟動後會載入一些共享的類及資源,其中共享類是在preload-classes檔案中被定義的,共享資源是在preload-resources中被定義的。其他Dalvik程序是被zygote程序孵化出來的,所以這些類和資源載入後,新的Dalvik程序就可以直接使用這些類和資源就達到了共享目的。

zygote程序對應的程式是app_process,該程式在system/bin目錄下。

zygote孵化出的第一個Dalvik程序是SystemServer,該程序對應的程式依然是app_process,因為該程序是從app_process中孵化出來的。

SystemServer中建立了一個Socket客戶端,之後所有的Dalvik程序都將通過該Socket客戶端間接被啟動,Ams負責管理這個客戶端。如果需要啟動新的APK程序時,Ams會通過該Socket客戶端向zygote程序的Socket服務端傳送一個啟動命令,然後zygote會孵化出新的程序。

這樣的架構有兩個特點:

1、每一個程序都是一個Dalvik虛擬機器,Dalvik虛擬機器是一種類似於java虛擬機器的程式。

2、zygote程序會預先裝載共享類和共享資源,這些類和資源其實就是SDK中定義的大部分類和資源。當通過zygote孵化出新程序後,新的APK只需要去載入APK自身包含的類和資源,這樣多個APK就可以共享Framework資源了。

和Dalvik虛擬機器有聯絡的可執行程式有哪些?

1.dalvikvm

java程式執行時都是由一個虛擬機器來解釋java位元組碼,將這些位元組碼翻譯成本地CPU指令碼然後執行。dalvikvm的作用就是建立一個虛擬機器並執行引數中指定的java類。

2.dvz

dvz的作用是從zygote程序中孵化出一個新的程序,新程序其實就是一個Dalvik虛擬機器。該程序與dalvikvm啟動的虛擬機器相比,區別是該程序中已經預裝了Framework的大部分類和資源。

3.app_process

Framework在啟動時需要載入執行兩個特定java類,一個是ZygoteInit.java,一個是SystemServer.java。為了方便使用,系統才提供了一個app_process程序,該程序會自動執行這兩個類,app_process其實就是使用dalvikvm啟動ZygoteInit.java,啟動後會載入Framework中得大部分類和資源。

Zygote是如何啟動的?

  1. 在init.rc中配置Zygote啟動引數
  2. 啟動Socket服務埠,當Zygote服務從app_process開始啟動後,會啟動一個Dalvik虛擬機器,虛擬機器第一個執行的java類就是ZygoteInit.java,該類第一個重要的工作就是啟動一個Socket服務埠,該Socket埠用於接收啟動新程序的命令。
  3. 載入preload-classes,在Zygote類的main()函式中,建立完Socket服務端後還不能立即孵化出新的程序,因為這個“卵”還沒有必須的“核酸”,這個“核酸”就是指預裝的Framework大部分類及資源。
  4. 載入preload-resources,preload-resources包含兩類資源,一類是drawable資源,一類是color資源。載入這些資源是在preloadResource()函式中完成的,該函式呼叫preloadDrawable()和preloadColorStateLists()載入這兩類資源,原理就是把這些資源讀出來放到一個全域性變數中,只要該類物件不被銷燬,這些全域性變數就會一直儲存。
  5. 使用fork啟動新的程序,fork是Linux系統的一個系統呼叫,作用就是複製當前程序產生一個新的程序。除了程序id不同,新程序將擁有和原始程序完全相同的程序資訊。程序的資訊包括該程序所開啟的檔案描述符列表、所分配的記憶體等。當新程序被建立後,兩個程序將共享已經分配的記憶體空間,如果其中一個需要向記憶體中寫入資料時,作業系統才複製一份目標地址空間,並將要寫的資料寫入到新的地址中。這種“僅當寫的時候才複製”的機制可以最大限度的在多個程序中共享實體記憶體。

SystemServer 程序是如何啟動的?

SystemServer程序是Zygote孵化出的第一個程序,然後再配置SystemServer程序的環境。

1.啟動各種系統服務執行緒

SystemServer程序在Android執行環境中扮演了“神經中樞”的作用,APK應用中能夠直接互動的大部分系統服務都在該程序中執行,常見的有WindowManagerServer(Wms)ActivityManagerService(Ams)、PackageManagerServer(Pms),這些系統服務都是以一個執行緒的方式存在於SystemServer程序中。

2.啟動第一個Activity

當以上服務執行緒都啟動後,其中Ams服務是systemReady()呼叫完成最後啟動的,在Ams的systemReady()函式的最後一段程式碼則發出了啟動任務佇列中最上面一個Activity訊息。

在Ams的startHomeActivityLocked()中,系統發出了一個category欄位包含CATEGORY_HOME的intent,程式碼如下:

intent.setComponent(mTopComponent);
if(mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL){
    intent.addCategory(Intent.CATEGORY_HOME);
}

只要應用宣告自己能夠響應該Intent,那麼就可以被認為是Home程式。當系統中有多個程式能夠響應該Intent時,系統會彈出一個對話方塊,讓使用者選擇啟動哪個程式,也允許使用者記住該選擇。

到此第一個Activity就啟動了。