在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,这也许就是为什么要把它称为Zygote(受精卵)的原因吧。由于Zygote进程在Android系统中有着如此重要的地位,本文将详细分析它的启动过程。

        在前面一篇文章Android应用程序进程启动过程的源代码分析中,我们看到了,当ActivityManagerService启动一个应用程序的时候,就会通过Socket与Zygote进程进行通信,请求它fork一个子进程出来作为这个即将要启动的应用程序的进程;在前面两篇文章Android应用程序安装过程源代码分析Android系统默认Home应用程序(Launcher)的启动过程源代码分析中,我们又看到了,系统中的两个重要服务PackageManagerService和ActivityManagerService,都是由SystemServer进程来负责启动的,而SystemServer进程本身是Zygote进程在启动的过程中fork出来的。

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

[plain] view plaincopy
  1. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server  
  2.     socket zygote stream 666  
  3.     onrestart write /sys/android_power/request_state wake  
  4.     onrestart write /sys/power/state on  
  5.     onrestart restart media  
  6.     onrestart restart netd  

        前面的关键字service告诉init进程创建一个名为"zygote"的进程,这个zygote进程要执行的程序是/system/bin/app_process,后面是要传给app_process的参数。

        接下来的socket关键字表示这个zygote进程需要一个名称为"zygote"的socket资源,这样,系统启动后,我们就可以在/dev/socket目录下看到有一个名为zygote的文件。这里定义的socket的类型为unix domain socket,它是用来作本地进程间通信用的,具体可以参考前面一篇文章Android学习启动篇提到的一书《Linux内核源代码情景分析》的第七章--基于socket的进程间通信。前面我们说到的ActivityManagerService就是通这个socket来和zygote进程通信请求fork一个应用程序进程的了。

        最后的一系列onrestart关键字表示这个zygote进程重启时需要执行的命令。

        关于init.rc文件的更多信息,请参考system/core/init/readme.txt文件。

        了解了这个信息之后,我们就知道Zygote进程要执行的程序便是system/bin/app_process了,它的源代码位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。在继续分析Zygote进程启动的过程之前,我们先来看看它的启动序列图:

 

      下面我们就详细分析每一个步骤。

        Step 1. app_process.main

        这个函数定义在frameworks/base/cmds/app_process/app_main.cpp文件中:

  1. int main(int argc, const charconst argv[])  
  2. {  
  3.     // These are global variables in ProcessState.cpp  
  4.     mArgC = argc;  
  5.     mArgV = argv;  
  6.   
  7.     mArgLen = 0;  
  8.     for (int i=0; i<argc; i++) {  
  9.         mArgLen += strlen(argv[i]) + 1;  
  10.     }  
  11.     mArgLen--;  
  12.   
  13.     AppRuntime runtime;  
  14.     const char *arg;  
  15.     argv0 = argv[0];  
  16.   
  17.     // Process command line arguments  
  18.     // ignore argv[0]  
  19.     argc--;  
  20.     argv++;  
  21.   
  22.     // Everything up to '--' or first non '-' arg goes to the vm  
  23.   
  24.     int i = runtime.addVmArguments(argc, argv);  
  25.   
  26.     // Next arg is parent directory  
  27.     if (i < argc) {  
  28.         runtime.mParentDir = argv[i++];  
  29.     }  
  30.   
  31.     // Next arg is startup classname or "--zygote"  
  32.     if (i < argc) {  
  33.         arg = argv[i++];  
  34.         if (0 == strcmp("--zygote", arg)) {  
  35.             bool startSystemServer = (i < argc) ?  
  36.                 strcmp(argv[i], "--start-system-server") == 0 : false;  
  37.             setArgv0(argv0, "zygote");  
  38.             set_process_name("zygote");  
  39.             runtime.start("com.android.internal.os.ZygoteInit",  
  40.                 startSystemServer);  
  41.         } else {  
  42.             set_process_name(argv0);  
  43.   
  44.             runtime.mClassName = arg;  
  45.   
  46.             // Remainder of args get passed to startup class main()  
  47.             runtime.mArgC = argc-i;  
  48.             runtime.mArgV = argv+i;  
  49.   
  50.             LOGV("App process is starting with pid=%d, class=%s.\n",  
  51.                 getpid(), runtime.getClassName());  
  52.             runtime.start();  
  53.         }  
  54.     } else {  
  55.         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");  
  56.         fprintf(stderr, "Error: no class name or --zygote supplied.\n");  
  57.         app_usage();  
  58.         return 10;  
  59.     }  
  60.   
  61. }  

        这个函数的主要作用就是创建一个AppRuntime变量,然后调用它的start成员函数。AppRuntime这个类我们在Android应用程序进程启动过程的源代码分析一文中已经有过介绍了,它同样是在frameworks/base/cmds/app_process/app_main.cpp文件中定义:[cpp] view plaincopy

 

  1. class AppRuntime : public AndroidRuntime  
  2. {  
  3.     ......  
  4. };  

        它约继承于AndroidRuntime类, AndroidRuntime类定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

  1. ......  
  2.   
  3. static AndroidRuntime* gCurRuntime = NULL;  
  4.   
  5. ......  
  6.   
  7. AndroidRuntime::AndroidRuntime()  
  8. {  
  9.     ......  
  10.   
  11.     assert(gCurRuntime == NULL);        // one per process  
  12.     gCurRuntime = this;  
  13. }  

        当AppRuntime对象创建时,会调用其父类AndroidRuntime的构造函数,而在AndroidRuntime类的构造函数里面,会将this指针保存在静态全局变量gCurRuntime中,这样,当其它地方需要使用这个AppRuntime对象时,就可以通过同一个文件中的这个函数来获取这个对象的指针:

  1. AndroidRuntime* AndroidRuntime::getRuntime()  
  2. {  
  3.     return gCurRuntime;  
  4. }  

        回到上面的main函数中,由于我们在init.rc文件中,设置了app_process启动参数--zygote和--start-system-server,因此,在main函数里面,最终会执行下面语句:

  1. runtime.start("com.android.internal.os.ZygoteInit",  
  2. rtSystemServer);  

        这里的参数startSystemServer为true,表示要启动SystemServer组件。由于AppRuntime没有实现自己的start函数,它继承了父类AndroidRuntime的start函数,因此,下面会执行AndroidRuntime类的start函数。