圖解 | Android系統(tǒng)的啟動(dòng)

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ù),

  1. init.zygote32.rc,Zygote進(jìn)程的執(zhí)行程序路徑為/system/bin/app_process
  2. init.zygote64.rc,Zygote進(jìn)程的執(zhí)行程序路徑為/system/bin/app_process64
  3. init.zygote32_64.rc,會(huì)啟動(dòng)兩個(gè)Zygote進(jìn)程,有兩個(gè)執(zhí)行程序,32為主模式
  4. 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)了。

image

綜上,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é):

image

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ù)

image

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)用程序信息,然后展示,就不具體分析了。

image

總結(jié)

Android系統(tǒng)啟動(dòng)的核心流程如下:

  1. Linux內(nèi)核啟動(dòng)
  2. init進(jìn)程啟動(dòng)
  3. init進(jìn)程fork出Zygote進(jìn)程
  4. Zygote進(jìn)程fork出SystemServer進(jìn)程
  5. SystemServer進(jìn)程啟動(dòng)各項(xiàng)服務(wù)(PMS、AMS等)
  6. AMS服務(wù)啟動(dòng)Launcher桌面
image

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)行在自己的工作線程。

參考資料


更多性感文章,關(guān)注原創(chuàng)技術(shù)公眾號(hào):哈利迪ei

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容