通过上一节Android   init进程启动的分析可知,init进程在启动过程中,解析并处理了init.rc和init.hardware.rc两个初始化脚本文件,在两个初始化脚本文件里,定义了一系列的service   section,这些service在boot触发器下,通过class_start default依次启动,其过程总结如下:
            1. init 解析init.rc
            2. init 将init.rc里的service放到队列里面等待触发器的触发
            3. init通过 action_for_each_trigger("boot",   action_add_queue_tail);触发boot Action
            4. 依次执行boot下的Commands,包括class_start default命令
            5. 所有的service默认的class为默认值:default,所以,所有init.rc中的service都被启动
            zygote服务启动
            通过init.rc中对zygote服务的描述可知,其对应的程序为:/system/bin/app_process
                      service   zygote /system/bin/app_process -Xzygote /system/bin --zygote   --start-system-server
                      socket zygote stream 666
                      onrestart   write /sys/android_power/request_state wake
                      onrestart write   /sys/power/state on
                      onrestart restart media 
            该服务会在on boot时触发,其程序为/system/bin/app_process,服务名为zygote,-Xzygote   /system/bin --zygote --start-system-server为参数列表。
            在创建了zygote 服务后,在目录下建立一个stream   socket文件/dev/socket/zygote,权限为666,当zygote服务重启时,重启media服务
            通过find ./ -name Android.mk -exec grep -l app_process {} \;   命令,查找到,它在./frameworks/base/cmds/app_process/目录中被编译,其主要入口文件为:
            ./frameworks/base/cmds/app_process/app_main.cpp
            找到该程序的main入口函数,
            int main(int argc, const char* const   argv[])
                  {
                      // These are global variables in   ProcessState.cpp
                      mArgC = argc;
                      mArgV =   argv;
                      mArgLen = 0;
                      for (int i=0; i< argc; i++)   {
                          mArgLen += strlen(argv[i]) +   1;
                          }
                      mArgLen--;
                      AppRuntime   runtime;
                      const char *arg;
                      const char   *argv0;
                      argv0 = argv[0];
                      // Process command line   arguments
                      // ignore   argv[0]
                      argc--;
                      argv++;
                      // Everything up to   '--' or first non '-' arg goes to the vm
                      //   在zygote服务的参数列表中,以‘--和非‘-’开头的参数,是dalvik的参数:/system/bin--zygote   --start-system-server,交给Vm来处理
                      int i = runtime.addVmArguments(argc,   argv);
                      // 找到zygote的目录:/system/bin
                      if (i < argc)   {
                          runtime.mParentDir = argv[i++];
                      }
                      //   如果接下来的参数是:--zygote --start-system-server的话,设置argv0=“zygote”,startSystemServer=   true,启动java VM
                      if (i < argc) {
                          arg =   argv[i++];
                          if (0 == strcmp("--zygote", arg))   {
                              bool startSystemServer = (i < argc)   ?
                              strcmp(argv[i], "--start-system-server") == 0 :   false;
                              setArgv0(argv0,   "zygote");
                              set_process_name("zygote");
                              runtime.start("com.android.internal.os.ZygoteInit",
                              startSystemServer);
                      }   else {
                          set_process_name(argv0);
                          runtime.mClassName   = arg;
                          // Remainder of args get passed to startup class   main()
                          runtime.mArgC = argc-i;
                          runtime.mArgV =   argv+i;
                          LOGV("App process is starting with pid=%d,   class=%s.\n",
                          getpid(),   runtime.getClassName());
                          runtime.start();
                          }
                      }   else {
                              LOG_ALWAYS_FATAL("app_process: no class name or   --zygote supplied.");
                              fprintf(stderr, "Error: no class name   or --zygote   supplied.\n");
                              app_usage();
                              return   10;
                          }
                  } 
            根据service zygote的参数,启动VM:
            runtime.start("com.android.internal.os.ZygoteInit",   startSystemServer);
            runtime是AppRuntime的对象,AppRuntime是AndroidRuntime的子类:
            
            runtime.start方法在AndroidRuntime里实现:
            void AndroidRuntime::start(const char* className, const bool   startSystemServer)
                  {
                      LOGD("\n>>>>>>>>>>>>>>   AndroidRuntime START   <<<<<<<<<<<<<<\n");        //logcat里显眼的字样
                      char*   slashClassName = NULL;
                      char* cp;
                      JNIEnv*   env;
                      blockSigpipe();
                      /* 
                      * 'startSystemServer   == true' means runtime is obslete and not run from
                      * init.rc anymore,   so we print out the boot start event here.
                      */
                      if   (startSystemServer) {
                      /* track our progress through the boot sequence   */
                      const int LOG_BOOT_PROGRESS_START =   3000;
                      LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
                      ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
                      }
                      const   char* rootDir = getenv("ANDROID_ROOT"); // 取得Android的根目录:/system
                      if   (rootDir == NULL) {
                      rootDir = "/system";
                      if   (!hasDir("/system")) {
                      LOG_FATAL("No root directory specified, and   /android does not exist.");
                      goto   bail;
                      }
                      setenv("ANDROID_ROOT", rootDir,   1);
                      }
                      //const char* kernelHack =   getenv("LD_ASSUME_KERNEL");
                      //LOGD("Found LD_ASSUME_KERNEL='%s'\n",   kernelHack); 
                      /* start the virtual machine */
                      //   启动Dalvik虚拟机,在AndroidRuntime::startVm方法中,设备了大量VM的参数,后调用JNI_CreateJavaVM(pJavaVM,   pEnv, &initArgs),通过JNI启动虚拟机
                      if (startVm(&mJavaVM, &env)   != 0) 
                      goto bail;
                      /*
                      * Register android   functions.
                      */
                      if (startReg(env) < 0) { //   注册系统使用的JNI函数
                      LOGE("Unable to register all android   natives\n");
                      goto bail;
                      }         jclass   stringClass;
                      jobjectArray strArray;
                      jstring   classNameStr;
                      jstring startSystemServerStr;
                      stringClass =   env->FindClass("java/lang/String");        //   从Dalvik虚拟机里,查找到String类,
                      assert(stringClass != NULL);         strArray   = env->NewObjectArray(2, stringClass, NULL);        //   创建一个String数组,有两个元素(strArray = new String[2])
                      assert(strArray !=   NULL);
                      classNameStr = env->NewStringUTF(className);        //   创建一个Java   String对象,初始值为:className,其实是start第一个参数:com.android.internal.os.ZygoteInit
                      assert(classNameStr   != NULL);
                      env->SetObjectArrayElement(strArray, 0,   classNameStr);        // 设置strArray 第一个元素的值为:classNameStr (strArray[0]   =classNameStr)
                      startSystemServerStr =   env->NewStringUTF(startSystemServer ? "true" : "false");        // 创建一个Java   String对象,初始值为:startSystemServer   ,其实是start第二个参数:true
                      env->SetObjectArrayElement(strArray, 1,   startSystemServerStr);        // 设置strArray 第二个元素的值为:strArray[1]   =startSystemServerStr
                      /*
                      * Start VM. This thread becomes   the main thread of the VM, and will
                      * not return until the VM   exits.
                      */
                      // 根据上面的解释可知:准备启动Java   VM,并且创建VM的主线程,只要VM不退出,这个主线程一直运行。
                      jclass   startClass;
                      jmethodID startMeth;
                      for (cp = slashClassName;   *cp != '\0'; cp++)        // 
              将com.android.internal.os.ZygoteInit中的包分隔符‘.’换成‘/’即:com/android/internal/os/ZygoteInit
                      if   (*cp == '.')
                      *cp = '/';
                      startClass =   env->FindClass(slashClassName);         //   从VM中查找ZygoteInit类,难道它要在VM里加载这个类。。。。
                      if (startClass == NULL)   {
                      LOGE("JavaVM unable to locate class '%s'\n",   slashClassName);
                      /* keep going */
                      } else   {
                      startMeth = env->GetStaticMethodID(startClass,   "main",
                      "([Ljava/lang/String;)V"); // 
                      查找到com/android/internal/os/ZygoteInit类中的main方法ID,接合Java文件命名规则,你能更深刻的理解,为什么主类名要和文件名一致,并且main方法为static方法。
                      if   (startMeth == NULL) {
                      LOGE("JavaVM unable to find main() in '%s'\n",   className);
                      /* keep going */
                      } else   {
                      env->CallStaticVoidMethod(startClass, startMeth,   strArray);        //   调用ZygoteInit类里的main方法,这不是运行ZygoteInit这个JAVA程序吗!!
                      #if 0
                      if   (env->ExceptionCheck())
                      threadExitUncaughtException(env);
                      #endif
                          }
                      }
                      LOGD("Shutting   down VM\n");
                      if (mJavaVM->DetachCurrentThread() !=   JNI_OK)
                      LOGW("Warning: unable to detach main   thread\n");
                      if (mJavaVM->DestroyJavaVM() !=   0)
                      LOGW("Warning: VM did not shut down   cleanly\n");
                      bail:
                      free(slashClassName);
                  } 
            由上面的分析可知,AndroidRuntime::start方法实现了下面功能:
            1>   通过startVm来启动虚拟机,并且注册了一些系统JNI函数,由于这个时候VM里还没有程序,只是个空的VM执行环境
            2>   通过AndroidRuntime::start的参数,在JNI代码里构建第一个Java程序ZygoteInit,将其作为VM的主线程,同时给其传递两个JNI构建的参数:
            "com/android/internal/os/ZygoteInit"和"true"
            总结:
            Android系统的启动是由init进程加载并启动了里面的/system/bin/app_process程序作为zygote服务,然后在zygote服务里执行runtime.start启动Dalvik虚拟机,加载了ZygoteInit类作为Dalvik虚拟机的第一个主线程。至此,Android的Java运行环境就准备完毕了。