1. 從 init 開始(init.cpp)
init 進程是用戶空間啟動的第一個進程,init 通過:
解析 init.rc 文件 -> 創(chuàng)建 Service 對象 -> Service.start() -> fork() -> execve() 來啟動 zygote 進程
2. zygote 啟動 (app_main.cpp)
在 zygote 的 main() 函數(shù)中主要做了下面幾件事
- 初始化AppRuntime
- 設置進程名為 “zygote”
- AndroidRuntime.start() 啟動 ZygoteInit 類,進入 Java 世界(AppRuntime 是 AndroidRuntime 的子類)
這里重點是最后一步,start() 函數(shù)里幾個重要的步驟是:
- startVm() 啟動虛擬機,配置各種虛擬機的參數(shù)
- startReg() 注冊大量 native 函數(shù)
- JNIEvn->CallStaticVoidMethod() 調(diào)用 ZygoteInit 類的 main() 函數(shù)
3. ZygoteInit 初始化
- 創(chuàng)建 ZygoteServer,并建立 Socket 監(jiān)聽
- preload(),預加載大量的類和資源文件
- startSystemServer(),通過一次 fork 啟動 system_server 進程
- 通過 ZygoteServer.runSelectLoop() 處理客戶端發(fā)起的 Socket 連接
- startSystemServer() 中 fork 出 system_server 進程之后,調(diào)用 handleSystemServerProcess() ,最終走到 RuntimeInit.zygoteInit() 的分支進行一些初始化的操作
- nativeZygoteInit() -> AndroidRuntime.com_android_internal_os_RuntimeInit_nativeZygoteInit() -> AppRuntim.onZygoteInit(),啟動 binder線程池
- applicationInit() -> invokeStaticMain(),這里的參數(shù)argv 從 ZygoteInit.startSystemServer() 一路傳遞過來,要啟動的 Java 類是 com.android.server.SystemServer。但這里并沒有直接調(diào)用 Java 類的 main() 函數(shù),而是在方法的末尾拋出一個異常 Zygote.MethodAndArgsCaller
- ZygoteInit.main() 方法捕獲 Zygote.MethodAndArgsCaller 異常,調(diào)用MethodAndArgsCaller 的 run() 方法,最終通過反射完成了SystemServer.main() 方法的調(diào)用,這樣做的目的是為了清空棧幀,提高棧幀利用率
4. SystemServer 啟動
SytemServer.main() -> SystemServer.run() :
- Looper.prepareMainLooper()
- createSystemContext() ->ActivityThread.systemMain() ->ActivityThread.attach(true)
(這里的boolean參數(shù)是為了用來區(qū)分是否是系統(tǒng)進程,普通應用進程啟動時會調(diào)用 ActivityThread.main() -> ActivityThread.attach(false),更多細節(jié)會在以后的應用啟動流程中進行分析): - ActivityThread.attach(true),關(guān)鍵部分代碼如下,主要就是初始化了 mInstrumentation 和 mInitialApplication 兩個變量
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();```
* mSystemContext = activityThread.getSystemContext() -> ContextImpl.createSystemContext(),關(guān)鍵代碼如下:
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread,
packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}
* startBootstrapServices() 、startCoreServices() 、startOtherServices() 啟動各類系統(tǒng)服務,這些服務都通過 SystemServiceManager.startService() 或 ServiceManager.addService() 來啟動和管理。啟動進行的不同的階段,會多次調(diào)用 SystemServiceManager.startBootPhase(int phase) -> service.onBootPhase(phase),傳入不同的 phase 值,不同的服務根據(jù) phase 值不同可以做對應的處理。
在 startOtherServices() 的最后,會調(diào)用 ActivityManagerService.systemReady(),這里面會調(diào)用 startHomeActivityLocked() 來啟動系統(tǒng)的第一個 app,也就是 Lanuncher。
* Looper.loop() 至此,系統(tǒng)的啟動部分邏輯就全部結(jié)束了