5張圖搞懂Android系統(tǒng)啟動(dòng)的核心流程~
大綱:
- Zygote啟動(dòng)
- SystemServer啟動(dòng)
- Launcher啟動(dòng)
- 總結(jié)
- 細(xì)節(jié)補(bǔ)充
- 參考資料
本文約1.9k字,閱讀大約8分鐘。
Android源碼基于8.0。
init進(jìn)程是Linux內(nèi)核啟動(dòng)完成后在用戶空間啟動(dòng)的第一個(gè)進(jìn)程,主要負(fù)責(zé)初始化工作、啟動(dòng)屬性服務(wù)、解析init.rc文件并啟動(dòng)Zygote進(jìn)程。
Zygote進(jìn)程是一個(gè)進(jìn)程孵化器,負(fù)責(zé)創(chuàng)建虛擬機(jī)實(shí)例、應(yīng)用程序進(jìn)程、系統(tǒng)服務(wù)進(jìn)程SystemServer。他通過fork(復(fù)制進(jìn)程)的方式創(chuàng)建子進(jìn)程,子進(jìn)程能繼承父進(jìn)程的系統(tǒng)資源如常用類、注冊(cè)的JNI函數(shù)、主題資源、共享庫等。
由于Zygote進(jìn)程啟動(dòng)時(shí)會(huì)創(chuàng)建虛擬機(jī)實(shí)例,由Zygote fork出的應(yīng)用程序進(jìn)程和SystemServer進(jìn)程則可以在內(nèi)部獲取到一個(gè)虛擬機(jī)實(shí)例副本。
Zygote啟動(dòng)
init進(jìn)程會(huì)解析配置文件init.rc,來啟動(dòng)一些需要在開機(jī)時(shí)就啟動(dòng)的系統(tǒng)進(jìn)程,如Zygote進(jìn)程、ServiceManager進(jìn)程等。
init.rc是由Android初始化語言編寫的腳本配置。由于Android 5.0開始支持了64bit程序,在init.rc里改成了通過${ro.zygote}的值來引入Zygote相關(guān)的配置,
//system/core/rootdir/init.rc
import /init.${ro.zygote}.rc
${ro.zygote}的取值有4種,在init.rc的同級(jí)目錄/system/core/rootdir下,可以看到4個(gè)Zygote相關(guān)的配置文件,表示系統(tǒng)所支持程序的bit位數(shù),
- init.zygote32.rc,Zygote進(jìn)程的執(zhí)行程序路徑為/system/bin/app_process
- init.zygote64.rc,Zygote進(jìn)程的執(zhí)行程序路徑為/system/bin/app_process64
- init.zygote32_64.rc,會(huì)啟動(dòng)兩個(gè)Zygote進(jìn)程,有兩個(gè)執(zhí)行程序,32為主模式
- init.zygote64_32.rc,會(huì)啟動(dòng)兩個(gè)Zygote進(jìn)程,有兩個(gè)執(zhí)行程序,64為主模式
我們看到init.zygote32.rc文件,
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
...
第一行中,service表示Zygote進(jìn)程以服務(wù)的形式來啟動(dòng),zygote則是進(jìn)程的名字,/system/bin/app_process是執(zhí)行程序的路徑,后面幾項(xiàng)則是傳給執(zhí)行程序的參數(shù),其中--start-system-server表示在Zygote進(jìn)程啟動(dòng)后需要啟動(dòng)SystemServer進(jìn)程。
然后是最后一行,Zygote進(jìn)程是使用socket來進(jìn)行跨進(jìn)程通信的,所以會(huì)創(chuàng)建一個(gè)名為zygote的socket,660表示訪問權(quán)限rw-rw----,表示文件擁有者和同一群組用戶具有讀寫權(quán)限。
init進(jìn)程啟動(dòng)后,通過fork和execve來啟動(dòng)Zygote進(jìn)程,
//system/core/init/service.cpp
bool Service::Start() {
//fork出子進(jìn)程
pid = fork();
if (pid == 0) {//子進(jìn)程會(huì)返回0,父進(jìn)程會(huì)返回子進(jìn)程的pid
//strs[0]是執(zhí)行程序的路徑,即execve會(huì)運(yùn)行app_process
if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
}
}
}
運(yùn)行執(zhí)行程序app_process的入口函數(shù)main,
//frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]){
if (zygote) {
//啟動(dòng)Zygote,進(jìn)入ZygoteInit.main函數(shù)
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
}
至此Zygote就正式啟動(dòng)了。

綜上,init進(jìn)程讀取配置文件init.rc后,fork出Zygote進(jìn)程,通過execve函數(shù)執(zhí)行Zygote的執(zhí)行程序app_process,進(jìn)入ZygoteInit類的main函數(shù)。
下面詳細(xì)分析app_main和ZygoteInit。
native層app_main
前邊可知app_main.cpp的main函數(shù)會(huì)調(diào)用runtime.start(),
//frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(...){
//1. 啟動(dòng)java虛擬機(jī)
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
//2. 為java虛擬機(jī)注冊(cè)JNI方法
if (startReg(env) < 0) {
return;
}
//根據(jù)傳入的參數(shù)找到ZygoteInit類和他的main函數(shù)
//3. 通過JNI調(diào)用ZygoteInit的main函數(shù)
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
Java層ZygoteInit
來到ZygoteInit的main函數(shù),
//ZygoteInit.java
public static void main(String argv[]) {
//是否要?jiǎng)?chuàng)建SystemServer
boolean startSystemServer = false;
//默認(rèn)的socket名字
String socketName = "zygote";
//是否要延遲資源的預(yù)加載
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
//在init.rc文件中,有--start-system-server參數(shù),表示要?jiǎng)?chuàng)建SystemServer
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
//init.rc沒有這個(gè)參數(shù),資源的預(yù)加載不會(huì)被延遲
enableLazyPreload = true;
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
//init.rc可以通過--socket-name=指定socket名字來覆蓋默認(rèn)值
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
}
}
//1. 創(chuàng)建服務(wù)端socket,名字為socketName即zygote
zygoteServer.registerServerSocket(socketName);
if (!enableLazyPreload) {
//2. 沒有被延遲,就預(yù)加載資源
preload(bootTimingsTraceLog);
}
if (startSystemServer) {
//3. fork并啟動(dòng)SystemServer進(jìn)程
startSystemServer(abiList, socketName, zygoteServer);
}
//4. 等待AMS請(qǐng)求(AMS會(huì)通過socket請(qǐng)求Zygote來創(chuàng)建應(yīng)用程序進(jìn)程)
zygoteServer.runSelectLoop(abiList);
}
總結(jié)一下native層的3個(gè)環(huán)節(jié)和Java層的4個(gè)環(huán)節(jié):

SystemServer啟動(dòng)
SystemServer進(jìn)程主要負(fù)責(zé)創(chuàng)建啟動(dòng)系統(tǒng)服務(wù)如AMS、WMS和PMS等。
從前邊可知SystemServer進(jìn)程由Zygote進(jìn)程fork出來并啟動(dòng),在ZygoteInit類中,
//ZygoteInit.java
private static boolean startSystemServer(...){
String args[] = {
//...
//啟動(dòng)的類名:
"com.android.server.SystemServer",
};
//fork進(jìn)程,由native層實(shí)現(xiàn)
pid = Zygote.forkSystemServer();
//處理SystemServer進(jìn)程
handleSystemServerProcess(parsedArgs);
}
private static void handleSystemServerProcess(...){
ZygoteInit.zygoteInit(...);
}
public static final void zygoteInit(...){
//啟動(dòng)binder線程池
ZygoteInit.nativeZygoteInit();
//內(nèi)部經(jīng)過層層調(diào)用,找到"com.android.server.SystemServer"類和他的main函數(shù),然后執(zhí)行
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
這里啟動(dòng)了binder線程池,SystemServer進(jìn)程就可以用binder機(jī)制來跨進(jìn)程通信了(Zygote進(jìn)程是用socket來通信的),接著進(jìn)入了SystemServer的main函數(shù),
//SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
//創(chuàng)建looper
Looper.prepareMainLooper();
//加載動(dòng)態(tài)庫libandroid_servers.so
System.loadLibrary("android_servers");
//創(chuàng)建系統(tǒng)上下文
createSystemContext();
//創(chuàng)建SSM,用于服務(wù)的創(chuàng)建、啟動(dòng)和生命周期管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//服務(wù)根據(jù)優(yōu)先級(jí)被分成3批來啟動(dòng):
//啟動(dòng)引導(dǎo)服務(wù),如AMS、PMS等
startBootstrapServices();
//啟動(dòng)核心服務(wù)
startCoreServices();
//啟動(dòng)其他服務(wù)
startOtherServices();
//開啟looper循環(huán)
Looper.loop();
}
看下AMS的啟動(dòng),
//SystemServer.java
private void startBootstrapServices() {
//由SSM創(chuàng)建啟動(dòng)
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
}
private void startOtherServices() {
//AMS準(zhǔn)備就緒
mActivityManagerService.systemReady(...);
}
總結(jié)一下,SystemServer進(jìn)程被創(chuàng)建后,主要做了3件事情:啟動(dòng)binder線程池、創(chuàng)建SystemServiceManager(SSM)、用SSM啟動(dòng)各種服務(wù)。

Launcher的啟動(dòng)
Launcher作為Android的桌面,用于管理應(yīng)用圖標(biāo)和桌面組件。
前邊可知SystemServer進(jìn)程會(huì)啟動(dòng)各種服務(wù),其中PackageManagerService啟動(dòng)后會(huì)將系統(tǒng)中的應(yīng)用程序安裝完成,然后由AMS來啟動(dòng)Launcher。
//SystemServer.java
private void startOtherServices() {
//AMS準(zhǔn)備就緒
mActivityManagerService.systemReady(...);
}
跟進(jìn)ActivityManagerService,
//ActivityManagerService.java
public void systemReady(...) {
//經(jīng)過層層調(diào)用來到startHomeActivityLocked
}
boolean startHomeActivityLocked(...) {
//最終會(huì)啟動(dòng)Launcher應(yīng)用的Activity
mActivityStarter.startHomeActivityLocked(...);
}
Activity類是Launcher.java,剩下的流程就是加載已安裝的應(yīng)用程序信息,然后展示,就不具體分析了。

總結(jié)
Android系統(tǒng)啟動(dòng)的核心流程如下:
- Linux內(nèi)核啟動(dòng)
- init進(jìn)程啟動(dòng)
- init進(jìn)程fork出Zygote進(jìn)程
- Zygote進(jìn)程fork出SystemServer進(jìn)程
- SystemServer進(jìn)程啟動(dòng)各項(xiàng)服務(wù)(PMS、AMS等)
- AMS服務(wù)啟動(dòng)Launcher桌面

Zygote進(jìn)程啟動(dòng)好服務(wù)端socket后,便會(huì)等待AMS的socket請(qǐng)求,來創(chuàng)建應(yīng)用程序進(jìn)程。
細(xì)節(jié)補(bǔ)充
- Zygote的跨進(jìn)程通信沒有使用binder,而是socket,所以應(yīng)用程序進(jìn)程的binder機(jī)制不是繼承而來,而是進(jìn)程創(chuàng)建后自己?jiǎn)?dòng)的。
- Zygote跨進(jìn)程通信之所以用socket而不是binder,是因?yàn)閎inder通信是多線程的,而Zygote需要在單線程狀態(tài)下fork子進(jìn)程來避免死鎖問題。
- PMS、AMS等系統(tǒng)服務(wù)啟動(dòng)后會(huì)調(diào)用ServiceManager.addService()注冊(cè),然后運(yùn)行在自己的工作線程。
參考資料
- 書籍 - Android進(jìn)階解密
- csdn - 為什么SystemServer進(jìn)程與Zygote進(jìn)程通訊采用Socket而不是Binder