zygote和system server啟動過程解析
Zygote的啟動過程解析。
Zygote實際上是一個用戶態應用程序,由啟動腳本負責啟動。在啟動腳本中Zygote叫做app_process。下面分析app_main.cpp中的啟動Zygote的過程。
main
|__設置runtime的mParentDir為/usr/bin,mArgC為zygote參數個數,mArgV為zygote參數(-Xzygote /system/bin --zygote --start-system-server)
|__runtime.start(AndroidRuntime::start)
|__設置環境變量ANDROID_ROOT
|__startVm():啟動VM
|__設置啟動虛擬機參數,如:checkjni,進程堆大小16MB等
|__調用JNI_CreateJavaVM()啟動虛擬機,之后JavaVM和虛擬機主線程的JNIEnv變量有效
|__startReg():向虛擬機主線程注冊JNI
|__com.android.internal.os.ZygoteInit.main(從JNI調用,從此進入JAVA世界)
|__registerZygoteSocket():創建Zygote服務端本地socket,用于監聽客戶端的連接請求
|__preloadClasses():預先加載preloaded-classes文件中指定的類(此過程耗時較大,好處是加快后續應用程序的啟動)
|__preloadResources():預先加載資源
|__gc():手動執行一次垃圾回收
|__startSystemServer():啟動一個子進程來運行system_server
|__硬編碼啟動system_server時使用的參數
|__調用Zygote.forkSystemServer()創建子進程
|__調用forkAndSpecializeCommon()創建子進程(調用fork()創建子進程且設置子進程相關uid、gid等屬性)
|__對于創建子進程失敗則直接將Zygote進程殺死(Zygote進程與system_server進程生死與共)
|__返回子進程ID
|__在子進程中調用handleSystemServerProcess()運行system_server
|__關閉父進程Zygote打開的本地服務端socket
|__執行RuntimeInit.zygoteInit()運行system_server
|__調用AppRuntime::onZygoteInit()。實際上是與binder建立聯系
|__調用invokeStaticMain()執行systemserver類的main函數
|__調用Class.forName()根據類名反射出類對象
|__調用類的getMethod()方法獲取systemserver類的main方法
|__調用ZygoteInit.MethodAndArgsCaller()拋出一個異常且該異常中包含systemserver類的main方法
|__runSelectLoopMode():使用多路復用I/O機制監聽連接到Zygote本地服務器的socket且執行響應處理
|__進入死循環監聽Zygote本地服務端socket,當有客戶端連接Zygote本地服務端socket后,調用ZygoteConnection.runOnce()執行該服務請求
|__ZygoteConnection.runOnce()
|__調用Zygote.forkAndSpecialize()函數創建一個子進程
|__在子進程中執行handleChildProc()處理客戶端請求
|__關閉父進程Zygote創建的服務端socket
|__執行RuntimeInit.zygoteInit()運行客戶端請求
|__調用AppRuntime::onZygoteInit()。實際上是與binder建立聯系
|__調用invokeStaticMain()執行客戶端請求類的main函數
|__調用Class.forName()根據類名反射出類對象
|__調用類的getMethod()方法獲取客戶端請求類的main方法
|__調用ZygoteInit.MethodAndArgsCaller()拋出一個異常且該異常中包含客戶端請求類的main方法
|__MethodAndArgsCaller.run():在異常處理函數處,用于啟動連接到Zygote服務器端socket的客戶端程序以及system_server主函數。(Zygote處理連接端數據時在最后使用拋異常的機制運行客戶端主函數)。
可以得出一個結論:system_server的啟動過程和其他應用進程的啟動過程是一致的,他們都是Zygote的子進程。
SystemServer啟動解析
main
|__System.loadLibrary(“android_servers”)加載JNI庫
|__init1()執行init1(JNI函數)
|__執行system_init()
|__設置參數準備將system_server加入binder
|__調用執行Java代碼的init2函數
|__創建一個線程執行android.server.ServerThread
|__啟動各種服務,如:電源管理、電池管理、藍牙等
|__等待新的服務請求。
|__最終將system_server添加到binder中
當有新的服務請求到后,system_server會調用服務請求的處理函數做如下事情:
1)與Zygote本地服務端Socket建立連接;
2)將待執行的類名組成指定的格式發送給Zygote;
3)Zygote接收到客戶端的請求后,調用ZygoteConnection.runOnce()執行該服務請求,即:創建一個子進程來運行指定類對象的main函數。