在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 plain copy
  1. servicezygote/system/bin/app_process-Xzygote/system/bin--zygote--start-system-server
  2. socketzygotestream666
  3. onrestartwrite/sys/android_power/request_statewake
  4. onrestartwrite/sys/power/stateon
  5. onrestartrestartmedia
  6. onrestartrestartnetd

前面的关键字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文件中:

[cpp] view plain copy
  1. intmain(intargc,constchar*constargv[])
  2. {
  3. //TheseareglobalvariablesinProcessState.cpp
  4. mArgC=argc;
  5. mArgV=argv;
  6. mArgLen=0;
  7. for(inti=0;i<argc;i++){
  8. mArgLen+=strlen(argv[i])+1;
  9. }
  10. mArgLen--;
  11. AppRuntimeruntime;
  12. constchar*arg;
  13. argv0=argv[0];
  14. //Processcommandlinearguments
  15. //ignoreargv[0]
  16. argc--;
  17. argv++;
  18. //Everythingupto'--'orfirstnon'-'arggoestothevm
  19. inti=runtime.addVmArguments(argc,argv);
  20. //Nextargisparentdirectory
  21. if(i<argc){
  22. runtime.mParentDir=argv[i++];
  23. }
  24. //Nextargisstartupclassnameor"--zygote"
  25. if(i<argc){
  26. arg=argv[i++];
  27. if(0==strcmp("--zygote",arg)){
  28. boolstartSystemServer=(i<argc)?
  29. strcmp(argv[i],"--start-system-server")==0:false;
  30. setArgv0(argv0,"zygote");
  31. set_process_name("zygote");
  32. runtime.start("com.android.internal.os.ZygoteInit",
  33. startSystemServer);
  34. }else{
  35. set_process_name(argv0);
  36. runtime.mClassName=arg;
  37. //Remainderofargsgetpassedtostartupclassmain()
  38. runtime.mArgC=argc-i;
  39. runtime.mArgV=argv+i;
  40. LOGV("Appprocessisstartingwithpid=%d,class=%s.\n",
  41. getpid(),runtime.getClassName());
  42. runtime.start();
  43. }
  44. }else{
  45. LOG_ALWAYS_FATAL("app_process:noclassnameor--zygotesupplied.");
  46. fprintf(stderr,"Error:noclassnameor--zygotesupplied.\n");
  47. app_usage();
  48. return10;
  49. }
  50. }

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

  1. classAppRuntime:publicAndroidRuntime
  2. {
  3. ......
  4. };

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

[cpp] view plain copy
  1. ......
  2. staticAndroidRuntime*gCurRuntime=NULL;
  3. ......
  4. AndroidRuntime::AndroidRuntime()
  5. {
  6. ......
  7. assert(gCurRuntime==NULL);//oneperprocess
  8. gCurRuntime=this;
  9. }

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

[cpp] view plain copy
  1. AndroidRuntime*AndroidRuntime::getRuntime()
  2. {
  3. returngCurRuntime;
  4. }

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

[cpp] view plain copy
  1. runtime.start("com.android.internal.os.ZygoteInit",
  2. rtSystemServer);

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

更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)studio使用NDK编译和调试(生成so文件)
  3. Android(安卓)混淆打包
  4. Service与Android系统设计(2)
  5. ORB_SLAM2在android studio上用cmake编译
  6. 带你一步一步手动实现Android热更新
  7. Eclipse下载Github用Android(安卓)Studio编辑的Android源码
  8. Android的APK反编译技术
  9. 为什么 Android(安卓)手机总是越用越慢

随机推荐

  1. ACCESS中Dlookup函数使用
  2. 95.自动挂载云盘
  3. 从IIC实测波形入手,搞懂IIC通信
  4. RGB-LCD液晶屏层叠显示测试
  5. 嵌入式开发,各类存储方式知多少?
  6. Bootstrap 学习 - 网格系统
  7. MPU6050姿态解算2-欧拉角&旋转矩阵
  8. FreeRTOS例程4-串口DMA收发不定长数据
  9. 欧拉角旋转
  10. FreeRTOS例程3-串口中断接收不定长的数据