Android Zygote進(jìn)程啟動(dòng)(一)

啟動(dòng)流程

Zygote進(jìn)程本身是一個(gè)native的程序,在init進(jìn)程啟動(dòng)后,會(huì)執(zhí)行init.rc中的內(nèi)容:

   service zygote /system/bin/app_process64 -Xzygote 
                              /system/bin --  zygote 
                              --start-system-server --socket-name=zygote
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks

1.第一行啟動(dòng)native service 名字為 “zygote”
2.關(guān)鍵字class 標(biāo)示,service的類型是main
3.關(guān)鍵字socket,標(biāo)示zygote進(jìn)程會(huì)創(chuàng)建一個(gè)名稱為“zygote”的socket
4.關(guān)鍵字onrestart 表示重啟需要執(zhí)行的命令

Zygote進(jìn)程對(duì)應(yīng)的主文件是app_main.cpp,當(dāng)它被啟動(dòng)后會(huì)進(jìn)入app_main.cpp 的main方法:

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

      AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

       ......

      while (i < argc) {
            const char* arg = argv[i++];
            if (strcmp(arg, "--zygote") == 0) {
                 zygote = true;
                 niceName = ZYGOTE_NICE_NAME;
                 // 在zygote進(jìn)程中重新命名進(jìn)程名
            } else if (strcmp(arg, "--start-system-server") == 0) {
                  startSystemServer = true;
                  // 代表啟動(dòng)SystemServer
            } else if (strcmp(arg, "--application") == 0) {
                  application = true;
            } else if (strncmp(arg, "--nice-name=", 12) == 0) {
                  niceName.setTo(arg + 12);
            } else if (strncmp(arg, "--", 2) != 0) {
                  className.setTo(arg);
                  break;
            } else {
                  --i;
                  break;
        }
    }

    ......
    
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }
}

代碼最后會(huì)調(diào)用runtime的start() 函數(shù),從最初的代碼中可以看到runtime是一個(gè)AppRuntime對(duì)象.

    class AppRuntime : public AndroidRuntime
    {
        ......
    }

AppRuntime是一個(gè)繼承于AndroidRuntime,runtime的start()函數(shù)將調(diào)用到AndroidRuntime::start()函數(shù):

void AndroidRuntime::start(const char* className
            , const Vector<String8>& options, bool zygote){
      
      ......
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    ......

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    
    .......

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
    #if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
   #endif
        }
    }
    
}

AndroidRuntime 方法中主要做了三件事:

  1. 調(diào)用startVM()啟動(dòng)虛擬機(jī),并且對(duì)JNIEnv的指針進(jìn)行賦值,為注冊(cè)jni代碼做準(zhǔn)備;
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){
      ......
          if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        return -1;
    }
    .......
}
  1. 調(diào)用startReq()注冊(cè)JNI方法
/*static*/ int AndroidRuntime::startReg(JNIEnv* env){
    ATRACE_NAME("RegisterAndroidNatives");
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    ALOGV("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}
  1. 調(diào)用ZygoteInit類的main方法,上面代碼中className 是由上一步傳遞過來的"com.android.internal.os.ZygoteInit" toSlashClassName方法是將.置換成/,將className內(nèi)容替換成了"com/android/internal/os/ZygoteInit"
    最終CallStaticVoidMethod調(diào)用ZygoteInit main 方法進(jìn)入java的世界,ZygoteInit中的執(zhí)行流程,將在
最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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