2025-05-23

前一篇https://www.aiwalls.com/kf/201203/123061.html 文章介紹瞭init進程的啟動過程,其中就有解析init.rc腳本,而根據其內容配置啟動瞭很多重要的服務:Servicemanager和zygote進程就奠定瞭Android的基礎,建立瞭真正的android空間。

 進程名稱               進程路徑

zygote                 /system/bin/app_process

servicemanager   /system/bin/servicemanager

bootanim            /system/bin/bootanimation

media                 /system/bin/mediaserver

這裡還都是在native世界中,此層分析哪個service沒有啟動,則找到相關的進程加打印即可,比較好分析,成功啟動的進程利用ps命令即可查看。

說明一下android中的兩個不同世界:

JAVA世界:運行基於 dalvik 虛擬機的 JAVA 程序

NATIVE世界:利用 C或C++開發的程序組成native世界。

下面開始分析 zygote 啟動流程:

代碼路徑:frameworks\base\cmds\app_process

啟動參數:

service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server

int main(int argc, const char* const argv[])

{

    // These are global variables in ProcessState.cpp

    mArgC = argc;

    mArgV = argv;

    // Next arg is startup classname or "–zygote"

    if (i < argc) {

        arg = argv[i++];

        if (0 == strcmp("–zygote", arg)) {   // init.rc 中的參數值

bool startSystemServer = (i < argc) ?

strcmp(argv[i], "–start-system-server") == 0 : false;

setArgv0(argv0, "zygote");

set_process_name("zygote");   // 利用prctl修改進程名稱

 runtime.start("com.android.internal.os.ZygoteInit",

startSystemServer);   // 這就是真正的重點!!!!
        }

….

}

下面開始建立 AndroidRuntime : 

路徑:frameworks\base\core\jni

class AppRuntime : public AndroidRuntime

AppRuntime  重載實現瞭 onStarted() , onZygoteInit(), onExit() 函數

runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);

–>  調用

/*

 * Start the Android runtime.  This involves starting the virtual machine

 * and calling the "static void main(String[] args)" method in the class

 * named by "className".

 */

void AndroidRuntime::start(const char* className, const bool startSystemServer)

{

 // 基本上再次看到這句話,說明系統重啟瞭

LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");

 

// 1、啟動 虛擬機

/* start the virtual machine */

 if (startVm(&mJavaVM, &env) != 0)

        goto bail;

 

// 2、註冊 jni 函數

/*

* Register android functions.

 */

if (startReg(env) < 0) {

LOGE("Unable to register all android natives\n");

goto bail;

}

/*

 3、從 com.android.internal.os.ZygoteInit 類中找到main函數,即調用

 ZygoteInit.java類中的main, 此時將進入到 java 世界。。。。

 */

startMeth = env->GetStaticMethodID(startClass, "main",

 "([Ljava/lang/String;)V");
 env->CallStaticVoidMethod(startClass, startMeth, strArray);

}

 

歡迎來到 JAVA 世界。。。。。

下面直接分析 ZygoteInit 類中的 main 函數:

路徑: frameworks\base\core\java\com\android\internal\os

public static void main(String argv[]) {

//1 、建立端口號為 50 的監聽套接字,用於接收

//    ActivityManangerService 的請求,Fork應用程序

registerZygoteSocket();

// 2、預加載類和資源,優化代碼時這裡可以想點辦法,不過有點麻煩

preloadClasses();

// 3、垃圾回收

gc();

// 4、啟動 SystemServer ,這個下面再重點講解

startSystemServer();

// 5、處理客戶連接與請求,具體由 ZygoteConnection.runOnce()處理

runSelectLoopMode();

}

 

SystemServer 的分析:

這個進程是由 zygote 產生的第一個進程

/**

* Prepare the arguments and fork for the system server process.

*/

private static boolean startSystemServer()

{

/* Hardcoded command line to start the system server */

String args[] = {

      "–setuid=1000",

      "–setgid=1000",            "–setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",

      "–capabilities=130104352,130104352",

      "–runtime-init",

      "–nice-name=system_server",        // process name  

      "com.android.server.SystemServer",   // class name

};

// 解析參數

parsedArgs = new ZygoteConnection.Arguments(args);

/* Request to fork the system server process */

pid = Zygote.forkSystemServer(

             parsedArgs.uid, parsedArgs.gid,

                    parsedArgs.gids, debugFlags, null);

/* For child process */

if (pid == 0) {

       handleSystemServerProcess(parsedArgs); // 後面講述

}

}

–>

forkSystemServer 這是一個jni 函數,調用:

\dalvik\vm\native\dalvik_system_Zygote.c 下面

static void Dalvik_dalvik_system_Zygote_forkSystemServer(

        const u4* args, JValue* pResult)

{

pid_t pid;

// 根據參數fork 出一個子進程,若成功調用一次則返回兩個值,子進程返回0,父進程返回子進程ID;否則,出錯返回-1

pid = forkAndSpecializeCommon(args);

if(pid > 0) {

gDvm.systemServerPid = pid;

        /* There is a slight window that the system server process has crashed

         * but it went unnoticed because we haven't published its pid yet. So

         * we recheck here just to make sure that all is well.

         */

        if (waitpid(pid, &status, WNOHANG) == pid) {

            LOGE("System server process %d has died. Restarting Zygote!", pid);

            kill(getpid(), SIGKILL);

        }

/*

這裡表示SystemServer進程退出,而其父進程是Zygote,所以這裡 kill掉的就是Zygote進程,即兩者都退出瞭。。。。

*/

}

}

 

Zygote 與 SystemServer 關系非常緊密,這裡有個小處理邏輯:

static pid_t forkAndSpecializeCommon(const u4* args)

{

setSignalHandler(); 

}

–>

static void setSignalHandler()

{

    int err;

    struct sigaction sa;

    memset(&sa, 0, sizeof(sa));

    sa.sa_handler = sigchldHandler; // 在此安裝瞭一個信號處理函數

    err = sigaction (SIGCHLD, &sa, NULL);

    …

}

信號處理函數:

/*

 * This signal handler is for zygote mode, since the zygote

 * must reap its children

 */

static void sigchldHandler(int s)

{

    pid_t pid;

    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {

        /*

         * If the just-crashed process is the system_server, bring down zygote

         * so that it is restarted by init and system server will be restarted

         * from there.

         */

        if (pid == gDvm.systemServerPid) {

            LOG(LOG_INFO, ZYGOTE_LOG_TAG,

                "Exit zygote because system server (%d) has terminated\n",

                (int) pid);

            kill(getpid(), SIGKILL);

        }

}

}

 

Zygote 啟動流程內容太多,下一篇從handleSystemServerProcess 處理流程講解

 摘自  andyhuabing的專欄 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *