美文网首页
Android Zygote进程启动(一)

Android Zygote进程启动(一)

作者: professorHe | 来源:发表于2017-08-11 16:50 被阅读0次
    启动流程

    Zygote进程本身是一个native的程序,在init进程启动后,会执行init.rc中的内容:

       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.第一行启动native service 名字为 “zygote”
    2.关键字class 标示,service的类型是main
    3.关键字socket,标示zygote进程会创建一个名称为“zygote”的socket
    4.关键字onrestart 表示重启需要执行的命令

    Zygote进程对应的主文件是app_main.cpp,当它被启动后会进入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进程中重新命名进程名
                } else if (strcmp(arg, "--start-system-server") == 0) {
                      startSystemServer = true;
                      // 代表启动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;
        }
    }
    

    代码最后会调用runtime的start() 函数,从最初的代码中可以看到runtime是一个AppRuntime对象.

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

    AppRuntime是一个继承于AndroidRuntime,runtime的start()函数将调用到AndroidRuntime::start()函数:

    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. 调用startVM()启动虚拟机,并且对JNIEnv的指针进行赋值,为注册jni代码做准备;
    int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){
          ......
              if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
            ALOGE("JNI_CreateJavaVM failed\n");
            return -1;
        }
        .......
    }
    
    1. 调用startReq()注册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. 调用ZygoteInit类的main方法,上面代码中className 是由上一步传递过来的"com.android.internal.os.ZygoteInit" toSlashClassName方法是将.置换成/,将className内容替换成了"com/android/internal/os/ZygoteInit"
      最终CallStaticVoidMethod调用ZygoteInit main 方法进入java的世界,ZygoteInit中的执行流程,将在

    相关文章

      网友评论

          本文标题:Android Zygote进程启动(一)

          本文链接:https://www.haomeiwen.com/subject/ugfwhxtx.html