Zygote进程启动过程的源代码分析

在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,zygote和system_server分别是Java世界的半边天,任何一个进程的死亡都会导致Java崩溃。
zygote本身是Native应用程序,与驱动内核无关。zygote最初的名字叫“app_process”,这个名字在Android.mk文件中指定,但在运行过程中被替换为"zygote"。

我们知道,Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中:

1.system/core/rootdir/init.rc:

[java]  view plain copy
  1. //关键字service告诉init进程创建一个名为"zygote"的进程,这个zygote进程要执行的程序是/system/bin/app_process,后面是要传给app_process的参数。  
  2. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server  
  3.     //socket关键字表示这个zygote进程需要一个名称为"zygote"的socket资源,这样,系统启动后,我们就可以在/dev/socket目录下看到有一个名为zygote的文件。这里定义的socket的类型为unix domain socket,它是用来作本地进程间通信用的  
  4.     socket zygote stream 666  
  5.     critical  
  6.     onrestart write /sys/android_power/request_state wake  
  7.     onrestart write /sys/power/state on  
  8.     onrestart restart media  
  9.     onrestart restart netd  
  10.     onrestart restart mlistener  
2.App_main.cpp

[java]  view plain copy
  1. int main(int argc, const charconst argv[])  
  2. {  
  3.     //zygote 是由init进程fork而来,init.rc文件中为zygote进程设置的启动参数如下  
  4.     //argc = 4  
  5.     //argv = [-Xzygote, /system/bin, --zygote, --start-system-server]  
  6.     // These are global variables in ProcessState.cpp  
  7.     mArgC = argc;  
  8.     mArgV = argv;  
  9.       
  10.     mArgLen = 0;  
  11.     for (int i=0; i<argc; i++) {  
  12.         mArgLen += strlen(argv[i]) + 1;  
  13.     }  
  14.     mArgLen--;  // mArgLen = 48  
  15.       
  16.     AppRuntime runtime;  
  17.     const char *arg;  
  18.     const char *argv0;  
  19.   
  20.     argv0 = argv[0]; //-Xzygote  
  21.   
  22.     // Process command line arguments  
  23.     // ignore argv[0]  
  24.     argc--;  
  25.     argv++;  
  26.   
  27.     //添加虚拟机参数选项  
  28.     //addVmArguments(3, [/system/bin, --zygote, --start-system-server])结果返回 i=0  
  29.     int i = runtime.addVmArguments(argc, argv);  
  30.   
  31.     // 设置虚拟机运行目录  
  32.     if (i < argc) {  
  33.         runtime.mParentDir = argv[i++]; //runtime.mParentDir =/system/bin  
  34.     }  
  35.     // i=1  
  36.     // Next arg is startup classname or "--zygote"  
  37.     if (i < argc) {  
  38.         arg = argv[i++]; //arg = --zygote  
  39.         //i=2  
  40.         if (0 == strcmp("--zygote", arg)) {  
  41.             //startSystemServer = true  
  42.             bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false;  
  43.             //设置argv0 的值为"zygote"  
  44.             setArgv0(argv0, "zygote");  
  45.             //设置进程名字  
  46.             set_process_name("zygote");  
  47.             // do last shutdown check  
  48.             doLastShutDownCheck();  
  49.             //调用Runtimed的start函数启动SystemServer进程,startSystemServer = true  
  50.             runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);  
  51.         } else {  
  52.             set_process_name(argv0);  
  53.   
  54.             runtime.mClassName = arg;  
  55.   
  56.             // Remainder of args get passed to startup class main()  
  57.             runtime.mArgC = argc-i;  
  58.             runtime.mArgV = argv+i;  
  59.   
  60.             LOGV("App process is starting with pid=%d, class=%s.\n",  
  61.                  getpid(), runtime.getClassName());  
  62.             runtime.start();  
  63.         }  
  64.     } else {  
  65.         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");  
  66.         fprintf(stderr, "Error: no class name or --zygote supplied.\n");  
  67.         app_usage();  
  68.         return 10;  
  69.     }  
  70. }  

这个函数的主要作用就是创建一个AppRuntime变量,然后调用它的start成员函数。AppRuntime类的声明和实现在App_main.cpp中,派生于AndroidRuntime类

3.AndroidRuntime.cpp

[java]  view plain copy
  1. void AndroidRuntime::start(const char* className, const bool startSystemServer)  
  2. {  
  3.     //className = "com.android.internal.os.ZygoteInit"  
  4.     //startSystemServer = true  
  5.     LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",className != NULL ? className : "(unknown)");  
  6.     char* slashClassName = NULL;  
  7.     char* cp;  
  8.     JNIEnv* env;  
  9.   
  10.     blockSigpipe();  
  11.   
  12.     /*  
  13.      * 'startSystemServer == true' means runtime is obslete and not run from  
  14.      * init.rc anymore, so we print out the boot start event here. 
  15.      */  
  16.     if (startSystemServer) {  
  17.         /* track our progress through the boot sequence */  
  18.         const int LOG_BOOT_PROGRESS_START = 3000;  
  19.         LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));  
  20.     }  
  21.     //获取环境变量android_root的根目录  
  22.     const char* rootDir = getenv("ANDROID_ROOT");  
  23.     if (rootDir == NULL) {  
  24.         rootDir = "/system"//如果获取结果为Null,则设置为"/system"  
  25.         if (!hasDir("/system")) {  
  26.             LOG_FATAL("No root directory specified, and /android does not exist.");  
  27.             goto bail;  
  28.         }  
  29.         setenv("ANDROID_ROOT", rootDir, 1);//重新设置环境变量ANDROID_ROOT  
  30.     }  
  31.   
  32.     //const char* kernelHack = getenv("LD_ASSUME_KERNEL");  
  33.     //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);  
  34.   
  35.     /* 启动虚拟机 */  
  36.     if (startVm(&mJavaVM, &env) != 0)  
  37.         goto bail;  
  38.   
  39.     /* 
  40.      * 注册JNI函数 
  41.      */  
  42.     if (startReg(env) < 0) {  
  43.         LOGE("Unable to register all android natives\n");  
  44.         goto bail;  
  45.     }  
  46.   
  47.     /* 
  48.      * We want to call main() with a String array with arguments in it. 
  49.      * At present we only have one argument, the class name.  Create an 
  50.      * array to hold it. 
  51.      */  
  52.     jclass stringClass;  
  53.     jobjectArray strArray;  
  54.     jstring classNameStr;  
  55.     jstring startSystemServerStr;  
  56.     //通过JNI查找java的java.lang.String类  
  57.     stringClass = env->FindClass("java/lang/String");  
  58.     assert(stringClass != NULL);  
  59.     //创建字符串数组String strArray[] = new String[2];  
  60.     strArray = env->NewObjectArray(2, stringClass, NULL);  
  61.     assert(strArray != NULL);  
  62.     //创建字符串classNameStr = new String("com.android.internal.os.ZygoteInit")  
  63.     classNameStr = env->NewStringUTF(className);  
  64.     assert(classNameStr != NULL);  
  65.     //设置字符串数组元素strArray[0]="com.android.internal.os.ZygoteInit"  
  66.     env->SetObjectArrayElement(strArray, 0, classNameStr);  
  67.     //创建字符串startSystemServerStr= new String("true")  
  68.     startSystemServerStr = env->NewStringUTF(startSystemServer ? "true" : "false");  
  69.     //设置字符串数组元素strArray[1]="true"  
  70.     env->SetObjectArrayElement(strArray, 1, startSystemServerStr);  
  71.   
  72.     /* 
  73.      * Start VM.  This thread becomes the main thread of the VM, and will 
  74.      * not return until the VM exits. 
  75.      */  
  76.     jclass startClass;  
  77.     jmethodID startMeth;  
  78.     //将字符串className 复制到slashClassName  
  79.     slashClassName = strdup(className);  
  80.     //为符合JNI规范,将com.android.internal.os.ZygoteInit中的.换成/,变为slashClassName = com/android/internal/os/ZygoteInit  
  81.     for (cp = slashClassName; *cp != '\0'; cp++)  
  82.         if (*cp == '.')  
  83.             *cp = '/';  
  84.     //查找Java类com/android/internal/os/ZygoteInit  
  85.     startClass = env->FindClass(slashClassName);  
  86.     if (startClass == NULL) {  
  87.         LOGE("JavaVM unable to locate class '%s'\n", slashClassName);  
  88.         /* keep going */  
  89.     } else {  
  90.         //找到ZygoteInit类的静态main方法的jMethodID  
  91.         startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");  
  92.         if (startMeth == NULL) {  
  93.             LOGE("JavaVM unable to find main() in '%s'\n", className);  
  94.             /* keep going */  
  95.         } else {  
  96.             //通过JNI调用ZygoteInit类的main函数,传递的参数为:  
  97.             //startClass = ZygoteInit  
  98.             //startMeth = main  
  99.             //strArray =["com.android.internal.os.ZygoteInit","true"]  
  100.             //在调用ZygoteInit类的main方法后,zygote就进入了java世界  
  101.             env->CallStaticVoidMethod(startClass, startMeth, strArray);  
  102.   
  103. #if 0  
  104.             if (env->ExceptionCheck())  
  105.                 threadExitUncaughtException(env);  
  106. #endif  
  107.         }  
  108.     }  
  109.     LOGD("Shutting down VM\n");  
  110.     if (mJavaVM->DetachCurrentThread() != JNI_OK)  
  111.         LOGW("Warning: unable to detach main thread\n");  
  112.     if (mJavaVM->DestroyJavaVM() != 0)  
  113.         LOGW("Warning: VM did not shut down cleanly\n");  
  114. bail:  
  115.     free(slashClassName);  
  116. }  
这个函数的作用是启动Android系统运行时库,它主要做了三件事情:
一是调用函数startVM启动虚拟机;
二是调用函数startReg注册JNI方法;
三是调用了com.android.internal.os.ZygoteInit类的main函数;

4.AndroidRuntime.cpp  启动虚拟机

[java]  view plain copy
  1. int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)  
  2. {  
  3.     int result = -1;  
  4.     JavaVMInitArgs initArgs; //虚拟机初始化参数  
  5.     JavaVMOption opt;        //虚拟机选项  
  6.     char propBuf[PROPERTY_VALUE_MAX];  
  7.     char stackTraceFileBuf[PROPERTY_VALUE_MAX];  
  8.     char dexoptFlagsBuf[PROPERTY_VALUE_MAX];  
  9.     char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];  
  10.     char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];  
  11.     char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];  
  12.     char extraOptsBuf[PROPERTY_VALUE_MAX];  
  13.     char* stackTraceFile = NULL;  
  14.     bool checkJni = false;  
  15.     bool checkDexSum = false;  
  16.     bool logStdio = false;  
  17.     enum {  
  18.       kEMDefault,  
  19.       kEMIntPortable,  
  20.       kEMIntFast,  
  21. #if defined(WITH_JIT)  
  22.       kEMJitCompiler,  
  23. #endif  
  24.     } executionMode = kEMDefault;  
  25.   
  26.   
  27.     property_get("dalvik.vm.checkjni", propBuf, ""); //读取"dalvik.vm.checkjni"属性值,“true” : “false”  
  28.     if (strcmp(propBuf, "true") == 0) {  
  29.         checkJni = true;  
  30.     } else if (strcmp(propBuf, "false") != 0) {  
  31.         /* property is neither true nor false; fall back on kernel parameter */  
  32.         property_get("ro.kernel.android.checkjni", propBuf, "");  
  33.         if (propBuf[0] == '1') {  
  34.             checkJni = true;  
  35.         }  
  36.     }  
  37.   
  38.     property_get("dalvik.vm.execution-mode", propBuf, "");//读取"dalvik.vm.execution-mode"属性值,“int:portable” : “int:fast”: “int:jit”  
  39.     if (strcmp(propBuf, "int:portable") == 0) {  
  40.         executionMode = kEMIntPortable;  
  41.     } else if (strcmp(propBuf, "int:fast") == 0) {  
  42.         executionMode = kEMIntFast;  
  43. #if defined(WITH_JIT)  
  44.     } else if (strcmp(propBuf, "int:jit") == 0) {  
  45.         executionMode = kEMJitCompiler;  
  46. #endif  
  47.     }  
  48.   
  49.     property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");//读取"dalvik.vm.stack-trace-file"属性值  
  50.   
  51.     property_get("dalvik.vm.check-dex-sum", propBuf, "");//读取"dalvik.vm.check-dex-sum"属性值,“true” : “false”  
  52.     if (strcmp(propBuf, "true") == 0) {  
  53.         checkDexSum = true;  
  54.     }  
  55.   
  56.     property_get("log.redirect-stdio", propBuf, "");  
  57.     if (strcmp(propBuf, "true") == 0) {  
  58.         logStdio = true;  
  59.     }  
  60.   
  61.     strcpy(enableAssertBuf, "-ea:");  
  62.     property_get("dalvik.vm.enableassertions", enableAssertBuf+4"");//读取"dalvik.vm.enableassertions"属性值  
  63.   
  64.     strcpy(jniOptsBuf, "-Xjniopts:");  
  65.     property_get("dalvik.vm.jniopts", jniOptsBuf+10"");//读取"dalvik.vm.jniopts"属性值  
  66.   
  67.     /* route exit() to our handler */  
  68.     opt.extraInfo = (void*) runtime_exit;  //设置退出函数  
  69.     opt.optionString = "exit";  
  70.     mOptions.add(opt);  
  71.   
  72.     /* route fprintf() to our handler */  
  73.     opt.extraInfo = (void*) runtime_vfprintf;//设置打印输出函数  
  74.     opt.optionString = "vfprintf";  
  75.     mOptions.add(opt);  
  76.   
  77.     opt.extraInfo = NULL;  
  78.   
  79.     /* enable verbose; standard options are { jni, gc, class } */  
  80.     //options[curOpt++].optionString = "-verbose:jni";  
  81.     opt.optionString = "-verbose:gc";  
  82.     mOptions.add(opt);  
  83.     //options[curOpt++].optionString = "-verbose:class";  
  84.   
  85.     strcpy(heapsizeOptsBuf, "-Xmx");  
  86.     property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4"16m");//读取"dalvik.vm.heapsize"属性值  
  87.     //LOGI("Heap size: %s", heapsizeOptsBuf);  
  88.     opt.optionString = heapsizeOptsBuf;  
  89.     mOptions.add(opt);  
  90.   
  91.     /* 
  92.      * Enable or disable dexopt features, such as bytecode verification and 
  93.      * calculation of register maps for precise GC. 
  94.      */  
  95.     property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");//读取"dalvik.vm.dexopt-flags"属性值  
  96.     if (dexoptFlagsBuf[0] != '\0') {  
  97.         const char* opc;  
  98.         const char* val;  
  99.   
  100.         opc = strstr(dexoptFlagsBuf, "v=");     /* verification */  
  101.         if (opc != NULL) {  
  102.             switch (*(opc+2)) {  
  103.             case 'n':   val = "-Xverify:none";      break;  
  104.             case 'r':   val = "-Xverify:remote";    break;  
  105.             case 'a':   val = "-Xverify:all";       break;  
  106.             default:    val = NULL;                 break;  
  107.             }  
  108.   
  109.             if (val != NULL) {  
  110.                 opt.optionString = val;  
  111.                 mOptions.add(opt);  
  112.             }  
  113.         }  
  114.   
  115.         opc = strstr(dexoptFlagsBuf, "o=");     /* optimization */  
  116.         if (opc != NULL) {  
  117.             switch (*(opc+2)) {  
  118.             case 'n':   val = "-Xdexopt:none";      break;  
  119.             case 'v':   val = "-Xdexopt:verified";  break;  
  120.             case 'a':   val = "-Xdexopt:all";       break;  
  121.             default:    val = NULL;                 break;  
  122.             }  
  123.   
  124.             if (val != NULL) {  
  125.                 opt.optionString = val;  
  126.                 mOptions.add(opt);  
  127.             }  
  128.         }  
  129.   
  130.         opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */  
  131.         if (opc != NULL) {  
  132.             opt.optionString = "-Xgenregmap";  
  133.             mOptions.add(opt);  
  134.   
  135.             /* turn on precise GC while we're at it */  
  136.             opt.optionString = "-Xgc:precise";  
  137.             mOptions.add(opt);  
  138.         }  
  139.     }  
  140.   
  141.     /* enable debugging; set suspend=y to pause during VM init */  
  142. #ifdef HAVE_ANDROID_OS  
  143.     /* use android ADB transport */  
  144.     opt.optionString ="-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";  
  145. #else  
  146.     /* use TCP socket; address=0 means start at port 8000 and probe up */  
  147.     LOGI("Using TCP socket for JDWP\n");  
  148.     opt.optionString ="-agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=0";  
  149. #endif  
  150.     mOptions.add(opt);  
  151.   
  152.     char enableDPBuf[sizeof("-Xdeadlockpredict:") + PROPERTY_VALUE_MAX];  
  153.     property_get("dalvik.vm.deadlock-predict", propBuf, "");  
  154.     if (strlen(propBuf) > 0) {  
  155.         strcpy(enableDPBuf, "-Xdeadlockpredict:");  
  156.         strcat(enableDPBuf, propBuf);  
  157.         opt.optionString = enableDPBuf;  
  158.         mOptions.add(opt);  
  159.     }  
  160.   
  161.     LOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");  
  162.     if (checkJni) {  
  163.         /* extended JNI checking */  
  164.         opt.optionString = "-Xcheck:jni";  
  165.         mOptions.add(opt);  
  166.   
  167.         /* set a cap on JNI global references */  
  168.         opt.optionString = "-Xjnigreflimit:2000";  
  169.         mOptions.add(opt);  
  170.   
  171.         /* with -Xcheck:jni, this provides a JNI function call trace */  
  172.         //opt.optionString = "-verbose:jni";  
  173.         //mOptions.add(opt);  
  174.     }  
  175.   
  176.     char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];  
  177.     property_get("dalvik.vm.lockprof.threshold", propBuf, "");  
  178.     if (strlen(propBuf) > 0) {  
  179.       strcpy(lockProfThresholdBuf, "-Xlockprofthreshold:");  
  180.       strcat(lockProfThresholdBuf, propBuf);  
  181.       opt.optionString = lockProfThresholdBuf;  
  182.       mOptions.add(opt);  
  183.     }  
  184.   
  185. #if defined(WITH_JIT)  
  186.     /* Force interpreter-only mode for selected opcodes. Eg "1-0a,3c,f1-ff" */  
  187.     char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];  
  188.     property_get("dalvik.vm.jit.op", propBuf, "");  
  189.     if (strlen(propBuf) > 0) {  
  190.         strcpy(jitOpBuf, "-Xjitop:");  
  191.         strcat(jitOpBuf, propBuf);  
  192.         opt.optionString = jitOpBuf;  
  193.         mOptions.add(opt);  
  194.     }  
  195.   
  196.     /* Force interpreter-only mode for selected methods */  
  197.     char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];  
  198.     property_get("dalvik.vm.jit.method", propBuf, "");  
  199.     if (strlen(propBuf) > 0) {  
  200.         strcpy(jitMethodBuf, "-Xjitmethod:");  
  201.         strcat(jitMethodBuf, propBuf);  
  202.         opt.optionString = jitMethodBuf;  
  203.         mOptions.add(opt);  
  204.     }  
  205. #endif  
  206.   
  207.     if (executionMode == kEMIntPortable) {  
  208.         opt.optionString = "-Xint:portable";  
  209.         mOptions.add(opt);  
  210.     } else if (executionMode == kEMIntFast) {  
  211.         opt.optionString = "-Xint:fast";  
  212.         mOptions.add(opt);  
  213. #if defined(WITH_JIT)  
  214.     } else if (executionMode == kEMJitCompiler) {  
  215.         opt.optionString = "-Xint:jit";  
  216.         mOptions.add(opt);  
  217. #endif  
  218.     }  
  219.   
  220.     if (checkDexSum) {  
  221.         /* perform additional DEX checksum tests */  
  222.         opt.optionString = "-Xcheckdexsum";  
  223.         mOptions.add(opt);  
  224.     }  
  225.   
  226.     if (logStdio) {  
  227.         /* convert stdout/stderr to log messages */  
  228.         opt.optionString = "-Xlog-stdio";  
  229.         mOptions.add(opt);  
  230.     }  
  231.   
  232.     if (enableAssertBuf[4] != '\0') {  
  233.         /* accept "all" to mean "all classes and packages" */  
  234.         if (strcmp(enableAssertBuf+4"all") == 0)  
  235.             enableAssertBuf[3] = '\0';  
  236.         LOGI("Assertions enabled: '%s'\n", enableAssertBuf);  
  237.         opt.optionString = enableAssertBuf;  
  238.         mOptions.add(opt);  
  239.     } else {  
  240.         LOGV("Assertions disabled\n");  
  241.     }  
  242.   
  243.     if (jniOptsBuf[10] != '\0') {  
  244.         LOGI("JNI options: '%s'\n", jniOptsBuf);  
  245.         opt.optionString = jniOptsBuf;  
  246.         mOptions.add(opt);  
  247.     }  
  248.   
  249.     if (stackTraceFileBuf[0] != '\0') {  
  250.         static const char* stfOptName = "-Xstacktracefile:";  
  251.   
  252.         stackTraceFile = (char*) malloc(strlen(stfOptName) +  
  253.             strlen(stackTraceFileBuf) +1);  
  254.         strcpy(stackTraceFile, stfOptName);  
  255.         strcat(stackTraceFile, stackTraceFileBuf);  
  256.         opt.optionString = stackTraceFile;  
  257.         mOptions.add(opt);  
  258.     }  
  259.   
  260.     /* extra options; parse this late so it overrides others */  
  261.     property_get("dalvik.vm.extra-opts", extraOptsBuf, "");  
  262.     parseExtraOpts(extraOptsBuf);  
  263.   
  264.     /* Set the properties for locale */  
  265.     {  
  266.         char langOption[sizeof("-Duser.language=") + 3];  
  267.         char regionOption[sizeof("-Duser.region=") + 3];  
  268.         strcpy(langOption, "-Duser.language=");  
  269.         strcpy(regionOption, "-Duser.region=");  
  270.         readLocale(langOption, regionOption);  
  271.         opt.extraInfo = NULL;  
  272.         opt.optionString = langOption;  
  273.         mOptions.add(opt);  
  274.         opt.optionString = regionOption;  
  275.         mOptions.add(opt);  
  276.     }  
  277.   
  278.     /* 
  279.      * We don't have /tmp on the device, but we often have an SD card.  Apps 
  280.      * shouldn't use this, but some test suites might want to exercise it. 
  281.      */  
  282.     opt.optionString = "-Djava.io.tmpdir=/sdcard";  
  283.     mOptions.add(opt);  
  284.   
  285.     initArgs.version = JNI_VERSION_1_4;  
  286.     initArgs.options = mOptions.editArray();  
  287.     initArgs.nOptions = mOptions.size();  
  288.     initArgs.ignoreUnrecognized = JNI_FALSE;  
  289.   
  290.     /* 
  291.      * Initialize the VM. 
  292.      * 
  293.      * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread. 
  294.      * If this call succeeds, the VM is ready, and we can start issuing 
  295.      * JNI calls. 
  296.      *调用JNI_CreateJavaVM函数创建虚拟机,关于虚拟机创建过程可参考dalvik\vm\Jni.c 
  297.      */  
  298.     if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {  
  299.         LOGE("JNI_CreateJavaVM failed\n");  
  300.         goto bail;  
  301.     }  
  302.   
  303.     result = 0;  
  304.   
  305. bail:  
  306.     free(stackTraceFile);  
  307.     return result;  
  308. }  

5.AndroidRuntime.cpp  注册JNI函数
第4步中已经创建好了虚拟机,因此需要给该虚拟机注册一些JNI函数。

[java]  view plain copy
  1. int AndroidRuntime::startReg(JNIEnv* env)  
  2. {  
  3.     /* 
  4.      * This hook causes all future threads created in this process to be 
  5.      * attached to the JavaVM.  (This needs to go away in favor of JNI 
  6.      * Attach calls.) 设置线程创建函数为javaCreateThreadEtc 
  7.      */  
  8.     androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);  
  9.   
  10.     LOGV("--- registering native functions ---\n");  
  11.   
  12.     /* 
  13.      * Every "register" function calls one or more things that return 
  14.      * a local reference (e.g. FindClass).  Because we haven't really 
  15.      * started the VM yet, they're all getting stored in the base frame 
  16.      * and never released.  Use Push/Pop to manage the storage. 
  17.      */  
  18.     env->PushLocalFrame(200);  
  19.     //注册JNI函数,所有的JNI函数存放在gRegJNI全局数组中  
  20.     if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {  
  21.         env->PopLocalFrame(NULL);  
  22.         return -1;  
  23.     }  
  24.     env->PopLocalFrame(NULL);  
  25.   
  26.     //createJavaThread("fubar", quickTest, (void*) "hello");  
  27.   
  28.     return 0;  
  29. }  

[java]  view plain copy
  1. //JNI函数注册方法  
  2. static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)  
  3. {  
  4.     for (size_t i = 0; i < count; i++) {  
  5.         if (array[i].mProc(env) < 0) {  
  6. #ifndef NDEBUG  
  7.             LOGD("----------!!! %s failed to load\n", array[i].mName);  
  8. #endif  
  9.             return -1;  
  10.         }  
  11.     }  
  12.     return 0;  
  13. }  

[html]  view plain copy
  1. //gRegJNI全局数组中  
  2. static const RegJNIRec gRegJNI[] = {  
  3.     REG_JNI(register_android_debug_JNITest),  
  4.     REG_JNI(register_com_android_internal_os_RuntimeInit),  
  5.     REG_JNI(register_android_os_SystemClock),  
  6.     REG_JNI(register_android_util_EventLog),  
  7.     REG_JNI(register_android_util_Log),  
  8.     REG_JNI(register_android_util_FloatMath),  
  9.     REG_JNI(register_android_text_format_Time),  
  10.     REG_JNI(register_android_pim_EventRecurrence),  
  11.     REG_JNI(register_android_content_AssetManager),  
  12.     REG_JNI(register_android_content_StringBlock),  
  13.     REG_JNI(register_android_content_XmlBlock),  
  14.     REG_JNI(register_android_emoji_EmojiFactory),  
  15.     REG_JNI(register_android_security_Md5MessageDigest),  
  16.     REG_JNI(register_android_text_AndroidCharacter),  
  17.     REG_JNI(register_android_text_AndroidBidi),  
  18.     REG_JNI(register_android_text_KeyCharacterMap),  
  19.     REG_JNI(register_android_os_Process),  
  20.     REG_JNI(register_android_os_Binder),  
  21.     REG_JNI(register_android_view_Display),  
  22.     REG_JNI(register_android_nio_utils),  
  23.     REG_JNI(register_android_graphics_PixelFormat),  
  24.     REG_JNI(register_android_graphics_Graphics),  
  25.     REG_JNI(register_android_view_Surface),  
  26.     REG_JNI(register_android_view_ViewRoot),  
  27.     REG_JNI(register_com_google_android_gles_jni_EGLImpl),  
  28.     REG_JNI(register_com_google_android_gles_jni_GLImpl),  
  29.     REG_JNI(register_android_opengl_jni_GLES10),  
  30.     REG_JNI(register_android_opengl_jni_GLES10Ext),  
  31.     REG_JNI(register_android_opengl_jni_GLES11),  
  32.     REG_JNI(register_android_opengl_jni_GLES11Ext),  
  33.     REG_JNI(register_android_opengl_jni_GLES20),  
  34.   
  35.     REG_JNI(register_android_graphics_Bitmap),  
  36.     REG_JNI(register_android_graphics_BitmapFactory),  
  37.     REG_JNI(register_android_graphics_BitmapRegionDecoder),  
  38.     REG_JNI(register_android_graphics_Camera),  
  39.     REG_JNI(register_android_graphics_Canvas),  
  40.     REG_JNI(register_android_graphics_ColorFilter),  
  41.     REG_JNI(register_android_graphics_DrawFilter),  
  42.     REG_JNI(register_android_graphics_Interpolator),  
  43.     REG_JNI(register_android_graphics_LayerRasterizer),  
  44.     REG_JNI(register_android_graphics_MaskFilter),  
  45.     REG_JNI(register_android_graphics_Matrix),  
  46.     REG_JNI(register_android_graphics_Movie),  
  47.     REG_JNI(register_android_graphics_NinePatch),  
  48.     REG_JNI(register_android_graphics_Paint),  
  49.     REG_JNI(register_android_graphics_Path),  
  50.     REG_JNI(register_android_graphics_PathMeasure),  
  51.     REG_JNI(register_android_graphics_PathEffect),  
  52.     REG_JNI(register_android_graphics_Picture),  
  53.     REG_JNI(register_android_graphics_PorterDuff),  
  54.     REG_JNI(register_android_graphics_Rasterizer),  
  55.     REG_JNI(register_android_graphics_Region),  
  56.     REG_JNI(register_android_graphics_Shader),  
  57.     REG_JNI(register_android_graphics_Typeface),  
  58.     REG_JNI(register_android_graphics_Xfermode),  
  59.     REG_JNI(register_android_graphics_YuvImage),  
  60.     REG_JNI(register_com_android_internal_graphics_NativeUtils),  
  61.   
  62.     REG_JNI(register_android_database_CursorWindow),  
  63.     REG_JNI(register_android_database_SQLiteCompiledSql),  
  64.     REG_JNI(register_android_database_SQLiteDatabase),  
  65.     REG_JNI(register_android_database_SQLiteDebug),  
  66.     REG_JNI(register_android_database_SQLiteProgram),  
  67.     REG_JNI(register_android_database_SQLiteQuery),  
  68.     REG_JNI(register_android_database_SQLiteStatement),  
  69.     REG_JNI(register_android_os_Debug),  
  70.     REG_JNI(register_android_os_FileObserver),  
  71.     REG_JNI(register_android_os_FileUtils),  
  72.     REG_JNI(register_android_os_MessageQueue),  
  73.     REG_JNI(register_android_os_ParcelFileDescriptor),  
  74.     REG_JNI(register_android_os_Power),  
  75.     REG_JNI(register_android_os_StatFs),  
  76.     REG_JNI(register_android_os_SystemProperties),  
  77.     REG_JNI(register_android_os_UEventObserver),  
  78.     REG_JNI(register_android_net_LocalSocketImpl),  
  79.     REG_JNI(register_android_net_NetworkUtils),  
  80.     REG_JNI(register_android_net_TrafficStats),  
  81.     REG_JNI(register_android_net_wifi_WifiManager),  
  82.     REG_JNI(register_android_nfc_NdefMessage),  
  83.     REG_JNI(register_android_nfc_NdefRecord),  
  84.     REG_JNI(register_android_os_MemoryFile),  
  85.     REG_JNI(register_com_android_internal_os_ZygoteInit),  
  86.     REG_JNI(register_android_hardware_Camera),  
  87.     REG_JNI(register_android_hardware_SensorManager),  
  88.     REG_JNI(register_android_media_AudioRecord),  
  89.     REG_JNI(register_android_media_AudioSystem),  
  90.     REG_JNI(register_android_media_AudioTrack),  
  91.     REG_JNI(register_android_media_JetPlayer),  
  92.     REG_JNI(register_android_media_ToneGenerator),  
  93.   
  94.     REG_JNI(register_android_opengl_classes),  
  95.     REG_JNI(register_android_bluetooth_HeadsetBase),  
  96.     REG_JNI(register_android_bluetooth_BluetoothAudioGateway),  
  97.     REG_JNI(register_android_bluetooth_BluetoothSocket),  
  98.     REG_JNI(register_android_bluetooth_ScoSocket),  
  99.     REG_JNI(register_android_server_BluetoothService),  
  100.     REG_JNI(register_android_server_BluetoothEventLoop),  
  101.     REG_JNI(register_android_server_BluetoothA2dpService),  
  102.     REG_JNI(register_android_server_Watchdog),  
  103.     REG_JNI(register_android_message_digest_sha1),  
  104.     REG_JNI(register_android_ddm_DdmHandleNativeHeap),  
  105.     REG_JNI(register_android_backup_BackupDataInput),  
  106.     REG_JNI(register_android_backup_BackupDataOutput),  
  107.     REG_JNI(register_android_backup_FileBackupHelperBase),  
  108.     REG_JNI(register_android_backup_BackupHelperDispatcher),  
  109.     REG_JNI(register_android_hardware_fm_fmradio),  
  110.     REG_JNI(register_android_app_NativeActivity),  
  111.     REG_JNI(register_android_view_InputChannel),  
  112.     REG_JNI(register_android_view_InputQueue),  
  113.     REG_JNI(register_android_view_KeyEvent),  
  114.     REG_JNI(register_android_view_MotionEvent),  
  115.   
  116.     REG_JNI(register_android_content_res_ObbScanner),  
  117.     REG_JNI(register_android_content_res_Configuration),  
  118. };  

6.ZygoteInit.java  调用了com.android.internal.os.ZygoteInit类的main函数

[java]  view plain copy
  1. public static void main(String argv[]) {  
  2. //传入的参数argv = ["com.android.internal.os.ZygoteInit","true"]  
  3.     try {  
  4.         //设置虚拟机的最小堆栈大小  
  5.         VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);  
  6.   
  7.         // Start profiling the zygote initialization.启动性能统计  
  8.         SamplingProfilerIntegration.start();  
  9.         //注册zygote等待客户端连接的socket  
  10.         registerZygoteSocket();  
  11.         EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());  
  12.         //预加载java类和资源  
  13.         preloadClasses();  
  14.         preloadResources();  
  15.         EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());  
  16.   
  17.         // Finish profiling the zygote initialization.结束统计并生成结果文件    
  18.         SamplingProfilerIntegration.writeZygoteSnapshot();  
  19.   
  20.         // Do an initial gc to clean up after startup,执行垃圾回收  
  21.         gc();  
  22.   
  23.         // If requested, start system server directly from Zygote  
  24.         if (argv.length != 2) {  
  25.         throw new RuntimeException(argv[0] + USAGE_STRING);  
  26.         }  
  27.   
  28.         if (argv[1].equals("true")) {  
  29.         //启动SystemServer进程  
  30.         startSystemServer();  
  31.         } else if (!argv[1].equals("false")) {  
  32.         throw new RuntimeException(argv[0] + USAGE_STRING);  
  33.         }  
  34.   
  35.         Log.i(TAG, "Accepting command socket connections");  
  36.         //boolean ZYGOTE_FORK_MODE = false; 因此调用runSelectLoopMode()函数  
  37.         if (ZYGOTE_FORK_MODE) {  
  38.         runForkMode();  
  39.         } else {  
  40.         runSelectLoopMode();  
  41.         }  
  42.         closeServerSocket(); //关闭socket  
  43.     } catch (MethodAndArgsCaller caller) {  
  44.         //捕获SytemServer进程调用RuntimeInit.java 中zygoteInit函数抛出的MethodAndArgsCaller异常  
  45.         caller.run();  
  46.     } catch (RuntimeException ex) {  
  47.         Log.e(TAG, "Zygote died with exception", ex);  
  48.         closeServerSocket();  
  49.         throw ex;  
  50.     }  
  51. }  

该main函数的作用:
<1>.调用registerZygoteSocket函数创建了一个socket接口,建立IPC通信的服务端;
<2> preloadClasses,preloadResources函数预加载类和资源
<2>.调用startSystemServer函数来启动SystemServer组件;
<3>.调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。

7.ZygoteInit.java  建立socket通信服务端

zygote 并没有采用binder通信机制,而是采用基于AF_UNIX类型的socket通信方式

[java]  view plain copy
  1. private static void registerZygoteSocket() {  
  2.     if (sServerSocket == null) {  
  3.         int fileDesc;  
  4.         try {  
  5.         //从环境变量中获取文件句柄,这个socket接口是通过文件描述符来创建的,这个文件描符代表的就是我们前面说的/dev/socket/zygote文件了。这个文件描述符是通过环境变量ANDROID_SOCKET_ENV得到的,关于socket的创建及环境变量的设置请参考init进程源码分析  
  6.         String env = System.getenv(ANDROID_SOCKET_ENV);  
  7.         fileDesc = Integer.parseInt(env);  
  8.         } catch (RuntimeException ex) {  
  9.         throw new RuntimeException(ANDROID_SOCKET_ENV + " unset or invalid", ex);  
  10.         }  
  11.   
  12.         try {  
  13.             //创建服务端socket,该socket将监听并接受客户端请求  
  14.         sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc));  
  15.         } catch (IOException ex) {  
  16.         throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex);  
  17.         }  
  18.     }  
  19. }  

8.ZygoteInit.java  预加载类和资源

[java]  view plain copy
  1. private static void preloadClasses() {  
  2.     final VMRuntime runtime = VMRuntime.getRuntime();  
  3.     //通过反射机制获取输入流,类资源文件为"preloaded-clprr"  
  4.     InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(PRELOADED_CLASSES);  
  5.     if (is == null) {  
  6.         Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");  
  7.     } else {  
  8.         Log.i(TAG, "Preloading classes...");  
  9.         long startTime = SystemClock.uptimeMillis();  
  10.   
  11.         // Drop root perms while running static initializers.  
  12.         //设置有效组ID和有效用户ID  
  13.         setEffectiveGroup(UNPRIVILEGED_GID);  
  14.         setEffectiveUser(UNPRIVILEGED_UID);  
  15.   
  16.         // Alter the target heap utilization.  With explicit GCs this  
  17.         // is not likely to have any effect.  
  18.         float defaultUtilization = runtime.getTargetHeapUtilization();  
  19.         runtime.setTargetHeapUtilization(0.8f);  
  20.   
  21.         // Start with a clean slate.  
  22.         runtime.gcSoftReferences();  
  23.         runtime.runFinalizationSync();  
  24.         Debug.startAllocCounting();  
  25.   
  26.         try {  
  27.         BufferedReader br= new BufferedReader(new InputStreamReader(is), 256);  
  28.   
  29.         int count = 0;  
  30.         String line;  
  31.         //一行一行读取文件内容  
  32.         while ((line = br.readLine()) != null) {  
  33.             // Skip comments and blank lines.  
  34.             line = line.trim();  
  35.             if (line.startsWith("#") || line.equals("")) {  
  36.                 continue;  
  37.             }  
  38.   
  39.             try {  
  40.                 if (Config.LOGV) {  
  41.                     Log.v(TAG, "Preloading " + line + "...");  
  42.                 }  
  43.                 //通过Java反射机制加载类,每一行储存的是类名  
  44.                 Class.forName(line);  
  45.                 if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {  
  46.                     if (Config.LOGV) {  
  47.                         Log.v(TAG," GC at " + Debug.getGlobalAllocSize());  
  48.                     }  
  49.                     runtime.gcSoftReferences();  
  50.                     runtime.runFinalizationSync();  
  51.                     Debug.resetGlobalAllocSize();  
  52.                 }  
  53.                 count++;  
  54.             } catch (ClassNotFoundException e) {  
  55.                 Log.w(TAG, "Class not found for preloading: " + line);  
  56.             } catch (Throwable t) {  
  57.                 Log.e(TAG, "Error preloading " + line + ".", t);  
  58.                 if (t instanceof Error) {  
  59.                     throw (Error) t;  
  60.                 }  
  61.                 if (t instanceof RuntimeException) {  
  62.                     throw (RuntimeException) t;  
  63.                 }  
  64.                 throw new RuntimeException(t);  
  65.             }  
  66.         }  
  67.   
  68.         Log.i(TAG, "...preloaded " + count + " classes in "  
  69.                 + (SystemClock.uptimeMillis()-startTime) + "ms.");  
  70.         } catch (IOException e) {  
  71.         Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);  
  72.         } finally {  
  73.         // Restore default.  
  74.         runtime.setTargetHeapUtilization(defaultUtilization);  
  75.   
  76.         Debug.stopAllocCounting();  
  77.   
  78.         // Bring back root. We'll need it later.  
  79.         setEffectiveUser(ROOT_UID);  
  80.         setEffectiveGroup(ROOT_GID);  
  81.         }  
  82.     }  
  83. }  
preloadClasses 执行时间比较长,也是导致android系统启动慢的原因。

加载共享资源

[java]  view plain copy
  1. private static void preloadResources() {  
  2.         final VMRuntime runtime = VMRuntime.getRuntime();  
  3.   
  4.         Debug.startAllocCounting();  
  5.         try {  
  6.             runtime.gcSoftReferences();  
  7.             runtime.runFinalizationSync();  
  8.             mResources = Resources.getSystem();  
  9.             mResources.startPreloading();  
  10.             if (PRELOAD_RESOURCES) {  
  11.                 Log.i(TAG, "Preloading resources...");  
  12.   
  13.                 long startTime = SystemClock.uptimeMillis();  
  14.                 TypedArray ar = mResources.obtainTypedArray(com.android.internal.R.array.preloaded_drawables);  
  15.                 int N = preloadDrawables(runtime, ar);  
  16.                 Log.i(TAG, "...preloaded " + N + " resources in "+ (SystemClock.uptimeMillis()-startTime) + "ms.");  
  17.   
  18.                 startTime = SystemClock.uptimeMillis();  
  19.                 ar = mResources.obtainTypedArray(  
  20.                         com.android.internal.R.array.preloaded_color_state_lists);  
  21.                 N = preloadColorStateLists(runtime, ar);  
  22.                 Log.i(TAG, "...preloaded " + N + " resources in "+ (SystemClock.uptimeMillis()-startTime) + "ms.");  
  23.             }  
  24.             mResources.finishPreloading();  
  25.         } catch (RuntimeException e) {  
  26.             Log.w(TAG, "Failure preloading resources", e);  
  27.         } finally {  
  28.             Debug.stopAllocCounting();  
  29.         }  
  30.     }  

9.ZygoteInit.java  启动SystemServer

[java]  view plain copy
  1. private static boolean startSystemServer()  
  2.            throws MethodAndArgsCaller, RuntimeException {  
  3.        /* Hardcoded command line to start the system server */  
  4.        String args[] = {  
  5.            "--setuid=1000",  
  6.            "--setgid=1000",  
  7.            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",  
  8.            "--capabilities=130104352,130104352",  
  9.            "--runtime-init",  
  10.            "--nice-name=system_server",  
  11.            "com.android.server.SystemServer",  
  12.        };  
  13.        ZygoteConnection.Arguments parsedArgs = null;  
  14.   
  15.        int pid;  
  16.   
  17.        try {  
  18.            parsedArgs = new ZygoteConnection.Arguments(args); //把字符串数组中的参数转换为Arguments对象  
  19.            /* 
  20.             * Enable debugging of the system process if *either* the command line flags 
  21.             * indicate it should be debuggable or the ro.debuggable system property 
  22.             * is set to "1" 
  23.             */  
  24.            int debugFlags = parsedArgs.debugFlags;  
  25.            if ("1".equals(SystemProperties.get("ro.debuggable")))  
  26.                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;  
  27.   
  28.            /* fork一个子进程作为SystemServer进程*/  
  29.            pid = Zygote.forkSystemServer(  
  30.                    parsedArgs.uid, parsedArgs.gid,  
  31.                    parsedArgs.gids, debugFlags, null,  
  32.                    parsedArgs.permittedCapabilities,  
  33.                    parsedArgs.effectiveCapabilities);  
  34.        } catch (IllegalArgumentException ex) {  
  35.            throw new RuntimeException(ex);  
  36.        }  
  37.   
  38.        /* For child process */  
  39.        if (pid == 0) {  
  40.         //SystemServer进程的初始化设置  
  41.            handleSystemServerProcess(parsedArgs);  
  42.        }  
  43.   
  44.        return true;  
  45.    }  
Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。

10.ZygoteInit.java  循环等待客户端的连接

[java]  view plain copy
  1. private static void runSelectLoopMode() throws MethodAndArgsCaller {  
  2.         ArrayList<FileDescriptor> fds = new ArrayList(); //存储所有客户端连接的socket文件句柄  
  3.         ArrayList<ZygoteConnection> peers = new ArrayList();//存储所有客户端连接  
  4.         FileDescriptor[] fdArray = new FileDescriptor[4];  
  5.   
  6.         fds.add(sServerSocket.getFileDescriptor());//保存先前创建用于等待客户端连接的服务端socket  
  7.         peers.add(null);  
  8.   
  9.         int loopCount = GC_LOOP_COUNT;  
  10.         while (true) {  
  11.             int index;  
  12.   
  13.             /* 
  14.              * Call gc() before we block in select(). 
  15.              * It's work that has to be done anyway, and it's better 
  16.              * to avoid making every child do it.  It will also 
  17.              * madvise() any free memory as a side-effect. 
  18.              * 
  19.              * Don't call it every time, because walking the entire 
  20.              * heap is a lot of overhead to free a few hundred bytes. 
  21.              */  
  22.             if (loopCount <= 0) {  
  23.                 gc();  
  24.                 loopCount = GC_LOOP_COUNT;  
  25.             } else {  
  26.                 loopCount--;  
  27.             }  
  28.   
  29.   
  30.             try {  
  31.                 fdArray = fds.toArray(fdArray);  
  32.                 //selectReadable内部调用select,使用多路复用I/O模型  
  33.                 //当有客户端连接时,selectReadable返回  
  34.                 index = selectReadable(fdArray);  
  35.             } catch (IOException ex) {  
  36.                 throw new RuntimeException("Error in select()", ex);  
  37.             }  
  38.   
  39.             if (index < 0) {  
  40.                 throw new RuntimeException("Error in select()");  
  41.             } else if (index == 0) {  
  42.                 //有一个客户端连接  
  43.                 ZygoteConnection newPeer = acceptCommandPeer();  
  44.                 peers.add(newPeer);  
  45.                 fds.add(newPeer.getFileDesciptor());  
  46.             } else {  
  47.                 boolean done;  
  48.                 //客户端发送了请求,peers.get(index)获取当前客户端的ZygoteConnection,并调用当前连接的runOnce()函数创建新的应用程序  
  49.                 done = peers.get(index).runOnce();  
  50.   
  51.                 if (done) {  
  52.                     peers.remove(index);  
  53.                     fds.remove(index);  
  54.                 }  
  55.             }  
  56.         }  
  57.     }  


zygote总结:
1.创建AppRuntime对象,并调用它的start函数;
2.调用startVm创建Java虚拟机;
3.调用startReg函数来注册JNI函数;
4.调用ZygoteInit类的main函数,从此就进入了Java世界;
5.调用registerZygoteSocket 注册一个服务端socket;
6.调用preloadClasses 函数加载类资源;
7.调用preloadResources函数加载系统资源;
8.调用startSystemServer函数创建SystemServer进程;
9.调用runSelectLoopMode函数进入服务端socket监听;

猜你喜欢

转载自blog.csdn.net/txbthy/article/details/18411403
今日推荐