首页 > 编程 > C++ > 正文

详细分析Android中实现Zygote的源码

2020-05-23 14:16:48
字体:大 中 小
来源:转载
供稿:网友

这篇文章主要介绍了详细分析Android中实现Zygote的源码,包括底层的C/C++代码以及Java代码部分入口,需要的朋友可以参考下

概述

在Android系统中,所有的应用程序进程,以及用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。zygote进程是通过复制自身的方式来创建System进程和应用程序进程的。由于zygote进程在启动时会在内部创建一个虚拟机实例,因此,通过复制zygote进程而得到的System进程和应用程序进程可以快速地在内部获得一个虚拟机实例拷贝。

zygote进程在启动完成之后,会马上将System进程启动起来,以便它可以将系统的关键服务启动起来。下面我们将介绍zygote进程的启动脚本,然后分析它和System进程的启动过程。

zygote分析

zygote进程的启动脚本如下:

 

 
  1. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server 
  2. class main 
  3. socket zygote stream 660 root system 
  4. onrestart write /sys/android_power/request_state wake 
  5. onrestart write /sys/power/state on 
  6. onrestart restart media 
  7. onrestart restart netd 

解析配置文件

在我之前的一篇博客中已经分析了init进程是如何启动service服务了,需要了解的同学可以参考这篇文章:Android init进程——

通过zygote服务的启动脚本,我们可以知道,zygote进程的实际是二进制文件app_process的调用,我们就从这个应用程序的main函数入手去分析一下zygote进程的启动过程,源码如下(/frameworks/base/cmds/app_process/app_main.cpp):

 

 
  1. /** 
  2. * 将-Xzygote加入到JavaVMOption中,返回/system/bin参数指向的下标 
  3. */ 
  4. int AndroidRuntime::addVmArguments(int argc, const char* const argv[]) 
  5. { 
  6. int i; 
  7.  
  8. for (i = 0; i < argc; i ++) { 
  9. if (argv[i][0] != '-') { 
  10. return i; 
  11. } 
  12. if (argv[i][1] == '-' && argv[i][2] == 0) { 
  13. return i + 1; 
  14. } 
  15.  
  16. JavaVMOption opt; 
  17. memset(&opt, 0, sizeof(opt)); 
  18. opt.optionString = (char*)argv[i]; 
  19. mOptions.add(opt); 
  20. } 
  21. return i; 
  22. } 
  23.  
  24. int main(int argc, char* const argv[]) 
  25. { 
  26. // zygote call parameters 
  27. // /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server 
  28.  
  29. // These are global variables in ProcessState.cpp 
  30. mArgC = argc; 
  31. mArgV = argv; 
  32.  
  33. mArgLen = 0; 
  34. for (int i = 0; i < argc; i ++) { 
  35. mArgLen += strlen(argv[i]) + 1; 
  36. } 
  37. // 去除末尾的空格 
  38. mArgLen--; 
  39.  
  40. AppRuntime runtime; 
  41. const char* argv0 = argv[0]; 
  42.  
  43. // Process command line arguments 
  44. // ignore argv[0] 
  45. argc --; 
  46. argv ++; 
  47.  
  48. // Everything up tp '--' or first non '-' arg goes to the vm 
  49. int i = runtime.addVmArguments(argc, argv); 
  50.  
  51. // Parse runtime arguments. Stop at first unrecognized option. 
  52. bool zygote = false; 
  53. bool startSystemServer = false; 
  54. bool application = false; 
  55. const char* parentDir = NULL; 
  56. const char* niceName = NULL; 
  57. const char* className = NULL; 
  58. while (i < argc) { 
  59. const char* arg = argv[i ++]; 
  60. if (!parentDir) { 
  61. parentDir = arg; 
  62. } else if (strcmp(arg, "--zygote") == 0) { 
  63. zygote = true; 
  64. niceName = "zygote"; 
  65. } else if (strcmp(arg, "--start-system-server") == 0) { 
  66. startSystemServer = true; 
  67. } else if (strcmp(arg, "--application") == 0) { 
  68. application = true; 
  69. } else if (strncmp(arg, "--nice-name=", 12)) { 
  70. niceName = arg + 12; 
  71. } else { 
  72. className = arg; 
  73. break; 
  74. } 
  75. } 
  76.  
  77. if (niceName && *niceName) { 
  78. setArgv0(argv0, niceName); 
  79. set_process_name(niceName); 
  80. } 
  81.  
  82. runtime.mParentDir = parentDir; 
  83.  
  84. if (zygote) { 
  85. // 进入到AppRuntime的start函数 
  86. runtime.start("com.android.internal.os.ZygoteInit", 
  87. startSystemServer? "start-system-server" : ""); 
  88. } else if (className) { 
  89. runtime.mClassName = className; 
  90. runtime.mArgc = argc - i; 
  91. runtime.mArgv = argv + i; 
  92. runtime.start("com.android.internal.os.RuntimeInit", application ? "application" : "tool"); 
  93. } else { 
  94. fprintf("stderr", "Error: no class name or --zygote supplied./n"); 
  95. app_usage(); 
  96. LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied"); 
  97. return 10; 
  98. } 
  99. } 

在zygote的main函数中,通过AppRuntime runtime代码创建了一个AppRuntime对象runtime,接下来Zygote进程就是通过它来进一步启动的。

init.rc中关于启动zygote命令中包含了–zygote参数,所以在if(strcmp(arg, “–zygote”) == 0)判断的时候,会将niceName赋值为”zygote”,然后通过set_process_name(niceName)函数将当前进程的名称设置为zygote。这也是为什么调用的脚本为/system/bin/app_process,而进程名为zygote的原因。set_process_name函数的源码如下(/system/core/libcutils/process_name.c):

 

 
  1. static const char* process_name = "unknown"; 
  2. void set_process_name(const char* new_name) 
  3. { 
  4. if (new_name == NULL) { 
  5. return; 
  6. } 
  7.  
  8. int len = strlen(new_name); 
  9. char* copy = (char*)malloc(len + 1); 
  10. strcpy(copy, new_name); 
  11. process_name = (const char*) copy; 
  12. } 

从init.rc文件中关于zygote进程的配置参数可知,Zygote进程传递给应用程序app_process的启动参数arg还包含一个”–start-system-server”选项。因此,在调用AppRuntime对象runtime的成员函数start时,第二个参数为”start-system-server”,表示zygote进程启动完成之后,需要将system进程启动起来。

AppRuntime分析

AppRuntime类的成员函数start是从父类AndroidRuntime继承下来的,因此,接下来我们就继续分析AndroidRuntime类的成员函数start的实现,函数源码位置:/frameworks/base/core/jni/AndroidRuntime.cpp:

 

 
  1. char* AndroidRuntime::toSlashClassName(const char* className) 
  2. { 
  3. char* result = strdup(className); 
  4. for (char* cp = result; *cp != '/0'; cp ++) { 
  5. if (*cp == '.') { 
  6. *cp = '/'; 
  7. } 
  8. } 
  9.  
  10. return result; 
  11. } 
  12.  
  13. /** 
  14. * Start the Android runtime. This involves starting the virtual machine 
  15. * and calling the "static void main(String[] args)" method int the class 
  16. * named by "className". 
  17. * 
  18. * 这两个参数的值分别为: 
  19. * const char* className = "com.android.internal.os.ZygoteInit"; 
  20. * const char* options = "start-system-server"; 
  21. */ 
  22. void AndroidRuntime::start(const char* className, const char* options) 
  23. { 
  24. ALOGD("/n>>>>> AndroidRuntime START %s <<<<<</n", 
  25. className != NULL ? className : "(unknown)"); 
  26.  
  27. /** 
  28. * 'startSystemServer == true' means runtime is obsolete and not run from 
  29. * init.rc anymore, so we print out the boot start event here. 
  30. */ 
  31. if (strcmp(options, "start-system-server") == 0) { 
  32. const int LOG_BOOT_PROGRESS_START = 3000; 
  33. LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 
  34. } 
  35.  
  36. // 设置ANDROID_ROOT环境变量 
  37. const char* rootDir = getenv("ANDROID_ROOT"); 
  38. if (rootDir == NULL) { 
  39. rootDir = "/system"; 
  40. if (!hasDir("/system")) { 
  41. LOG_FATAL("No root directory specified, and /android dose not exist."); 
  42. return; 
  43. } 
  44. setenv("ANDROID_ROOT", rootDir, 1); 
  45. } 
  46.  
  47.  
  48. JniInvocation jni_invocation; 
  49. jni_invocation.Init(NULL); 
  50. JNIEnv* env; 
  51. // 1. 创建虚拟机 
  52. if (startVm(&mJavaVM, &env) != 0) { 
  53. return; 
  54. } 
  55. onVmCreated(env); 
  56.  
  57. // 2. 注册JNI函数 
  58. if (startReg(env) < 0) { 
  59. ALOGE("Unable to register all android natives/n"); 
  60. return; 
  61. } 
  62.  
  63. jclass stringClass; 
  64. jobjectArray strArray; 
  65. jstring classNameStr; 
  66. jstring optionsStr; 
  67.  
  68. stringClass = env->FindClass("java/lang/String"); 
  69. assert(stringClass != NULL); 
  70. // 创建一个有两个元素的String数组,用Java代码表示为:String[] strArray = new String[2]; 
  71. strArray = env->NewObjectArray(2, stringClass, NULL); 
  72. assert(strArray != NULL); 
  73. classNameStr = env->NewStringUTF(className); 
  74. assert(classNameStr != NULL); 
  75. // 设置第一个元素为"com.android.internal.os.ZygoteInit" 
  76. env->SetObjectArrayElement(strArray, 0, classNameStr); 
  77. optionsStr = env->NewStringUTF(options); 
  78. // 设置第二个元素为"start-system-server" 
  79. env->SetObjectArrayElement(strArray, 1, optionsStr); 
  80.  
  81. // 将字符串"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit" 
  82. char* slashClassName = toSlashClassName(className); 
  83. jclass startClass = env->FindClass(slashClassName); 
  84. if (startClass == NULL) { 
  85. ALOGE("JavaVM unable to locate class '%s'/n", slashClassName); 
  86. } else { 
  87. jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); 
  88. if (startMeth == NULL) { 
  89. ALOGE("JavaVM unable to find main() in '%s/n'", className); 
  90. } else { 
  91. // 3. 
  92. // 通过JNI调用java函数,注意调用的是main函数,所属的类是"com.android.internal.os.ZygoteInit". 
  93. // 传递的参数是"com.android.internal.os.ZygoteInit true" 
  94. env->CallStaticVoidMethod(startClass, startMeth, strArray); 
  95. } 
  96. } 
  97. free(slashClassName); 
  98.  
  99. ALOGD("Shutting down VM/n"); 
  100. if (mJavaVM->DetachCurrentThread() != JNI_OK) { 
  101. ALOGW("Warning: unable to detach main thread/n"); 
  102. } 
  103. if (mJavaVM->DestoryJavaVM() != 0) { 
  104. ALOGW("Warning: VM did not shut down cleanly/n"); 
  105. } 
  106. } 

上述代码有几处关键点,分别是:

创建虚拟机。

注册JNI函数。

进入Java世界。

接下来,我们分别分析这三个关键点。

创建虚拟机——startVm

startVm并没有特别之处,就是调用JNI的虚拟机创建函数,但是创建虚拟机时的一些参数却是在startVm中确定的,其源码如下:

 

 
  1. #define PROPERTY_VALUE_MAX 92 
  2. /** 
  3. * Start the Dalvik Virtual Machine. 
  4. * 
  5. * Various arguments, most determined by system properties, are passed in. 
  6. * The "mOptions" vector is updated. 
  7. * 
  8. * Returns 0 on success. 
  9. */ 
  10. int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIENV** pEnv) 
  11. { 
  12. int result = -1; 
  13. JavaVMInitArgs initArgs; 
  14. JavaVMOption opt; 
  15. char propBuf[PROPERTY_VALUE_MAX]; 
  16. char stackTraceFileBuf[PROPERTY_VALUE_MAX]; 
  17. char dexoptFlagsBuf[PROPERTY_VALUE_MAX]; 
  18. char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX]; 
  19. char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX]; 
  20. char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX]; 
  21. char heapsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX]; 
  22. char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX]; 
  23. char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX]; 
  24. char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX]; 
  25. char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX]; 
  26. char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX]; 
  27. char extraOptsBuf[PROPERTY_VALUE_MAX]; 
  28. char* stackTraceFile = NULL; 
  29. bool checkJni = false; 
  30. bool checkDexSum = false; 
  31. bool logStdio = false; 
  32. enum { 
  33. KEMDefault, 
  34. KEMIntPortable, 
  35. KEMIntFast, 
  36. KEMJitCompiler, 
  37. } executionMode = KEMDefault; 
  38.  
  39. /** 
  40. * 这段代码是用了设置JNI_check选项的。JNI_check指的是Native层调用JNI函数时,系统所做的一些检查动作。 
  41. * 这个选项虽然能增加可靠性,但是还有一些副作用: 
  42. * 1. 因为检查工作比较耗时,所以会影响系统运行速度。 
  43. * 2. 有些检查工作比较耗时,一旦出错,整个进程会abort。 
  44. * 所以,JNI_check选项一般只在eng版本设置。 
  45. */ 
  46. property_get("dalvik.vm.checkjni", propBuf, ""); 
  47. if (strcmp(propBuf, "true") == 0) { 
  48. checkJni = true; 
  49. } else if (strcmp(propBuf, "false") != 0) { 
  50. property_get("ro.kernel.android.checkjni", propBuf, ""); 
  51. if (propBuf[0] == '1') { 
  52. checkJni = true; 
  53. } 
  54. } 
  55.  
  56. property_get("dalvik.vm.execution-mode", propBuf, ""); 
  57. if (strcmp(propBuf, "int:portable") == 0) { 
  58. executionMode = KEMIntPortable; 
  59. } else if (strcmp(propBuf, "int:fast") == 0) { 
  60. executionMode = KEMIntFast;  
  61. } else if (strcmp(propBuf, "int:jit") == 0) { 
  62. executionMode = KEMJitCompiler; 
  63. } 
  64.  
  65. // ... 省略大部分参数设置 
  66.  
  67. /** 
  68. * 设置虚拟机的heapsize,默认为16m。绝大多数厂商都会在build.prop文件里修改这个属性,一般是256m。 
  69. * heapsize不能设置得过小,否则在操作大尺寸的图片时无法分配所需的内存。 
  70. */ 
  71. strcpy(heapsizeOptsBuf, "-Xmx"); 
  72. property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m"); 
  73. opt.optionString = heapsizeOptsBuf; 
  74. mOptions.add(opt); 
  75.  
  76. // ...... 
  77.  
  78. if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { 
  79. ALOGE("JNI_CreateJavaVM failed/n"); 
  80. goto bail; 
  81. } 
  82.  
  83. result = 0; 
  84.  
  85. bail: 
  86. free(stackTraceFile); 
  87. return result; 
  88. } 

更多虚拟机参数的设置,我这里就不做特殊说明了,大家感兴趣可以自行google。(ps:因为我不太懂虚拟机这一块…)

注册JNI函数——startReg

上面讲了如何创建虚拟机,接下来需要给这个虚拟机注册一些JNI函数。正是因为后续的Java世界用到的一些函数是采用native方式实现的,所以才必须提前注册这些函数。

接下来,我们来看一下startReg函数的源码实现:

 

 
  1. int AndroidRuntime::startReg(JNIEnv* env) 
  2. { 
  3. // 设置Thread类的线程创建函数为javaCreateThreadEtc 
  4. androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc); 
  5.  
  6. ALOGV("--- registering native functions ---/n"); 
  7.  
  8. env->PushLocalFrame(200); 
  9.  
  10. if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { 
  11. env->PopLocalFrame(NULL); 
  12. return -1; 
  13. } 
  14. env->PopLocalFrame(NULL); 
  15.  
  16. return 0; 
  17. } 

关键是需要注册JNI函数,具体实现是由register_jni_procs函数实现的,我们来看一下这个函数的具体实现(/frameworks/base/core/jni/AndroidRuntime.cpp):

 

 
  1. static int register_jni_procs(const RegJNIRec array[], size_T count, JNIEnv* env) 
  2. { 
  3. for (size_t i = 0; i < count; i ++) { 
  4. if (array[i].mProc(env) < 0) { 
  5. #ifndef NDEBUG 
  6. ALOGD("------!!! %s failed to load/n", array[i].mName); 
  7. #endif 
  8. return -1; 
  9. } 
  10. } 
  11.  
  12. return 0; 
  13. } 

通过源码,我们可以看到,register_jni_procs只是对array数组的mProc函数的封装,而array数组指向的是gRegJNI数组,我们来看一下这个数组的实现:

 

 
  1. static const RegJNIRec gRegJNI[] = { 
  2. REG_JNI(register_android_debug_JNITest), 
  3. REG_JNI(register_com_android_internal_os_RuntimeInit), 
  4. REG_JNI(register_android_os_SystemClock), 
  5. REG_JNI(register_android_util_EventLog), 
  6. REG_JNI(register_android_util_Log), 
  7. REG_JNI(register_android_util_FloatMath), 
  8. REG_JNI(register_android_text_format_Time), 
  9. REG_JNI(register_android_content_AssetManager), 
  10. REG_JNI(register_android_content_StringBlock), 
  11. REG_JNI(register_android_content_XmlBlock), 
  12. REG_JNI(register_android_emoji_EmojiFactory), 
  13. REG_JNI(register_android_text_AndroidCharacter), 
  14. REG_JNI(register_android_text_AndroidBidi), 
  15. REG_JNI(register_android_view_InputDevice), 
  16. REG_JNI(register_android_view_KeyCharacterMap), 
  17. REG_JNI(register_android_os_Process), 
  18. REG_JNI(register_android_os_SystemProperties), 
  19. REG_JNI(register_android_os_Binder), 
  20. REG_JNI(register_android_os_Parcel), 
  21. REG_JNI(register_android_view_DisplayEventReceiver), 
  22. REG_JNI(register_android_nio_utils), 
  23. REG_JNI(register_android_graphics_Graphics), 
  24. REG_JNI(register_android_view_GraphicBuffer), 
  25. REG_JNI(register_android_view_GLES20DisplayList), 
  26. REG_JNI(register_android_view_GLES20Canvas), 
  27. REG_JNI(register_android_view_HardwareRenderer), 
  28. REG_JNI(register_android_view_Surface), 
  29. REG_JNI(register_android_view_SurfaceControl), 
  30. REG_JNI(register_android_view_SurfaceSession), 
  31. REG_JNI(register_android_view_TextureView), 
  32. REG_JNI(register_com_google_android_gles_jni_EGLImpl), 
  33. REG_JNI(register_com_google_android_gles_jni_GLImpl), 
  34. REG_JNI(register_android_opengl_jni_EGL14), 
  35. REG_JNI(register_android_opengl_jni_EGLExt), 
  36. REG_JNI(register_android_opengl_jni_GLES10), 
  37. REG_JNI(register_android_opengl_jni_GLES10Ext), 
  38. REG_JNI(register_android_opengl_jni_GLES11), 
  39. REG_JNI(register_android_opengl_jni_GLES11Ext), 
  40. REG_JNI(register_android_opengl_jni_GLES20), 
  41. REG_JNI(register_android_opengl_jni_GLES30), 
  42.  
  43. REG_JNI(register_android_graphics_Bitmap), 
  44. REG_JNI(register_android_graphics_BitmapFactory), 
  45. REG_JNI(register_android_graphics_BitmapRegionDecoder), 
  46. REG_JNI(register_android_graphics_Camera), 
  47. REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), 
  48. REG_JNI(register_android_graphics_Canvas), 
  49. REG_JNI(register_android_graphics_ColorFilter), 
  50. REG_JNI(register_android_graphics_DrawFilter), 
  51. REG_JNI(register_android_graphics_Interpolator), 
  52. REG_JNI(register_android_graphics_LayerRasterizer), 
  53. REG_JNI(register_android_graphics_MaskFilter), 
  54. REG_JNI(register_android_graphics_Matrix), 
  55. REG_JNI(register_android_graphics_Movie), 
  56. REG_JNI(register_android_graphics_NinePatch), 
  57. REG_JNI(register_android_graphics_Paint), 
  58. REG_JNI(register_android_graphics_Path), 
  59. REG_JNI(register_android_graphics_PathMeasure), 
  60. REG_JNI(register_android_graphics_PathEffect), 
  61. REG_JNI(register_android_graphics_Picture), 
  62. REG_JNI(register_android_graphics_PorterDuff), 
  63. REG_JNI(register_android_graphics_Rasterizer), 
  64. REG_JNI(register_android_graphics_Region), 
  65. REG_JNI(register_android_graphics_Shader), 
  66. REG_JNI(register_android_graphics_SurfaceTexture), 
  67. REG_JNI(register_android_graphics_Typeface), 
  68. REG_JNI(register_android_graphics_Xfermode), 
  69. REG_JNI(register_android_graphics_YuvImage), 
  70. REG_JNI(register_android_graphics_pdf_PdfDocument), 
  71.  
  72. REG_JNI(register_android_database_CursorWindow), 
  73. REG_JNI(register_android_database_SQLiteConnection), 
  74. REG_JNI(register_android_database_SQLiteGlobal), 
  75. REG_JNI(register_android_database_SQLiteDebug), 
  76. REG_JNI(register_android_os_Debug), 
  77. REG_JNI(register_android_os_FileObserver), 
  78. REG_JNI(register_android_os_MessageQueue), 
  79. REG_JNI(register_android_os_SELinux), 
  80. REG_JNI(register_android_os_Trace), 
  81. REG_JNI(register_android_os_UEventObserver), 
  82. REG_JNI(register_android_net_LocalSocketImpl), 
  83. REG_JNI(register_android_net_NetworkUtils), 
  84. REG_JNI(register_android_net_TrafficStats), 
  85. REG_JNI(register_android_net_wifi_WifiNative), 
  86. REG_JNI(register_android_os_MemoryFile), 
  87. REG_JNI(register_com_android_internal_os_ZygoteInit), 
  88. REG_JNI(register_android_hardware_Camera), 
  89. REG_JNI(register_android_hardware_camera2_CameraMetadata), 
  90. REG_JNI(register_android_hardware_SensorManager), 
  91. REG_JNI(register_android_hardware_SerialPort), 
  92. REG_JNI(register_android_hardware_UsbDevice), 
  93. REG_JNI(register_android_hardware_UsbDeviceConnection), 
  94. REG_JNI(register_android_hardware_UsbRequest), 
  95. REG_JNI(register_android_media_AudioRecord), 
  96. REG_JNI(register_android_media_AudioSystem), 
  97. REG_JNI(register_android_media_AudioTrack), 
  98. REG_JNI(register_android_media_JetPlayer), 
  99. REG_JNI(register_android_media_RemoteDisplay), 
  100. REG_JNI(register_android_media_ToneGenerator), 
  101.  
  102. REG_JNI(register_android_opengl_classes), 
  103. REG_JNI(register_android_server_NetworkManagementSocketTagger), 
  104. REG_JNI(register_android_server_Watchdog), 
  105. REG_JNI(register_android_ddm_DdmHandleNativeHeap), 
  106. REG_JNI(register_android_backup_BackupDataInput), 
  107. REG_JNI(register_android_backup_BackupDataOutput), 
  108. REG_JNI(register_android_backup_FileBackupHelperBase), 
  109. REG_JNI(register_android_backup_BackupHelperDispatcher), 
  110. REG_JNI(register_android_app_backup_FullBackup), 
  111. REG_JNI(register_android_app_ActivityThread), 
  112. REG_JNI(register_android_app_NativeActivity), 
  113. REG_JNI(register_android_view_InputChannel), 
  114. REG_JNI(register_android_view_InputEventReceiver), 
  115. REG_JNI(register_android_view_InputEventSender), 
  116. REG_JNI(register_android_view_InputQueue), 
  117. REG_JNI(register_android_view_KeyEvent), 
  118. REG_JNI(register_android_view_MotionEvent), 
  119. REG_JNI(register_android_view_PointerIcon), 
  120. REG_JNI(register_android_view_VelocityTracker), 
  121.  
  122. REG_JNI(register_android_content_res_ObbScanner), 
  123. REG_JNI(register_android_content_res_Configuration), 
  124.  
  125. REG_JNI(register_android_animation_PropertyValuesHolder), 
  126. REG_JNI(register_com_android_internal_content_NativeLibraryHelper), 
  127. REG_JNI(register_com_android_internal_net_NetworkStatsFactory), 
  128. }; 
  129.  
  130. #ifdef NDEBUG 
  131. #define REG_JNI(name) {name} 
  132. struct RegJNIRec { 
  133. int (*mProc)(JNIEnv*); 
  134. }; 
  135. #else 
  136. #define REG_JNI(name) {name, #name} 
  137. struct RegJNIRec { 
  138. int (*mProc)(JNIEnv*); 
  139. const char* mName; 
  140. }; 
  141. #endif 

可以看到,REG_JNI是一个宏,宏里面包括的就是那个参数为JNIEnv*,返回值为int的函数指针mProc,我们以register_android_debug_JNITest为例,源码位置为/frameworks/base/core/jni/android_debug_JNITest.cpp:

 

 
  1. #define NELEM(x) (sizeof(x)/sizeof(*(x))) 
  2.  
  3. int register_android_debug_JNITest(JNIEnv* env) 
  4. { 
  5. return jniRegisterNativeMethods(env, "android/debug/JNITest", gMethods, NELEM(gMethods)); 
  6. } 

可以看到,mProc其实就是为Java类注册JNI函数。

进入JAVA世界

可以看到CallStaticVoidMethod最终将调用com.android.internal.os.ZygoteInit的main函数,下面就来看一下这个Java世界的入口函数。源码位置:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,源码如下:

 

 
  1. public static void main(String argv[]) 
  2. { 
  3. try { 
  4. SamplingProfilerIntegration.start(); 
  5.  
  6. // 1. 注册zygote用的socket 
  7. registerZygoteSocket(); 
  8. EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); 
  9.  
  10. // 2. 预加载类和资源 
  11. preload(); 
  12. EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); 
  13.  
  14. SamplingProfilerIntegration.writeZygoteSnapshot(); 
  15.  
  16. // 强制执行一次垃圾收集 
  17. gc(); 
  18.  
  19. Trace.setTracingEnabled(false); 
  20.  
  21. if (argv.length != 2) { 
  22. throw new RuntimeException(argv[0] + USAGE_STRING); 
  23. } 
  24.  
  25. if (argv[1].equals("start-system-server")) { 
  26. // 3. 启动system-server 
  27. startSystemServer(); 
  28. } else if (!argv[1].equals("")) { 
  29. throw new RuntimeException(argv[0] + USAGE_STRING); 
  30. } 
  31.  
  32. Log.i(TAG, "Accepting command socket connections"); 
  33.  
  34. // 4. 进入请求应答模式 
  35. runSelectLoop(); 
  36. closeServerSocket(); 
  37.  
  38. } catch(MethodAndArgsCaller caller) { 
  39. caller.run(); 
  40. } catch(RuntimeException ex) { 
  41. Log.e(TAG, "Zygote died with exception", ex); 
  42. closeServerSocket(); 
  43. throw ex; 
  44. } 
  45. } 

上述代码中有5个重要的点,我已经通过标号标记出来了,接下来我们分别分析一下这5点函数的具体实现。

建立IPC通信服务端——registerZygoteSocket

zygote及系统中其他程序的通信没有使用Binder,而是采用了基于AF_UNIX类型的socket。registerZygoteSocket函数的使命正是建立这个Socket,实现代码如下:

 

 
  1. private static void registerZygoteSocket() 
  2. { 
  3. if (sServerSocket == null) { 
  4. int fileDesc; 
  5. try { 
  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. sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc)); 
  14. } catch(IOException ex) {  
  15. throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex); 
  16. } 
  17. } 
  18. } 
  19.  
  20. public class LocalServerSocket { 
  21. private final LocalSocketImpl impl; 
  22. private final LocalSocketAddress localAddress; 
  23.  
  24. private static final int LISTEN_BACKLOG = 50; 
  25.  
  26. /** 
  27. * Create a LocalServerSocket from a file descriptor that's already 
  28. * been created and bound. listen() will be called immediately on it. 
  29. * Used for cases where file descriptors are passed in via environment 
  30. * variables. 
  31. */ 
  32. public LocalServerSocket(FileDescriptor fd) throws IOException { 
  33. impl = new LocalSocketImpl(fd); 
  34. impl.listen(LISTEN_BACKLOG); 
  35. localAddress = impl.getSockAddress(); 
  36. } 
  37. } 

registerZygoteSocket很简单,就是创建一个服务端的socket。

预加载类和资源——preload

我们先来看一下preload函数实现:

 

 
  1. static void preload() 
  2. { 
  3. preloadClasses(); 
  4. preloadResources(); 
  5. preloadOpenGL(); 
  6. } 

preload函数里面分别调用了三个预加载函数,我们分别来分析一下这几个函数的实现。

首先是preloadClasses,函数实现如下:

 

 
  1. private static final int UNPRIVILEGED_UID = 9999; 
  2. private static final int UNPRIVILEGED_GID = 9999; 
  3.  
  4. private static final int ROOT_UID = 0; 
  5. private static final int ROOT_GID = 0; 
  6.  
  7. private static void preloadClasses() 
  8. { 
  9. final VMRuntime runtime = VMRuntime.getRuntime(); 
  10.  
  11. InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(PRELOADED_CLASSES); 
  12. if (is == null) { 
  13. Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + "."); 
  14. } else { 
  15. Log.i(TAG, "Preloading classes..."); 
  16. long startTime = SystemClock.uptimeMillis(); 
  17.  
  18. setEffectiveGroup(UNPRIVILEGED_GID); 
  19. setEffectiveGroup(UNPRIVILEGED_UID); 
  20.  
  21. float defaultUtilization = runtime.getTargetHeapUtilization(); 
  22. runtime.setTargetHeapUtilization(0.8f); 
  23.  
  24. System.gc(); 
  25. runtime.runFinalizationSync(); 
  26. Debug.startAllocCounting(); 
  27.  
  28. try { 
  29. // 创建一个缓冲区为256字符的输入流 
  30. BufferedReader br = new BufferdReader(new InputStreamReader(is), 256); 
  31. int count = 0; 
  32. String line; 
  33. while ((line = br.readLine()) != null) { 
  34. // skip comments and blank lines. 
  35. line = line.trim(); 
  36. if (line.startsWith("#") || line.equals("")) { 
  37. continue; 
  38. } 
  39.  
  40. try { 
  41. if (false) { 
  42. Log.v(TAG, "Preloading " + line + "..."); 
  43. } 
  44. Class.forName(line); 
  45. count ++; 
  46. } catch (ClassNotFoundException e) { 
  47. Log.w(TAG, "Class not found for preloading: " + line); 
  48. } catch (UnsatisfiedLinkError e) { 
  49. Log.w(TAG, "Problem preloading " + line + ": " + e); 
  50. } catch(Throwable t) { 
  51. Log.e(TAG, "Error preloading " + line + ".", t); 
  52. } 
  53. } 
  54. Log.i(TAG, "...preloaded " + count + " classes in " + (SystemClock.uptimeMillis()-startTime) + "ms."); 
  55. } catch (IOException e) { 
  56. Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e); 
  57. } finally { 
  58. IoUtils.closeQuietly(is); 
  59. runtime.setTargetHeapUtilization(defaultUtilization); 
  60.  
  61. runtime.preloadDexCaches(); 
  62. Debug.stopAllocCounting(); 
  63.  
  64. setEffectiveUser(ROOT_UID); 
  65. setEffectiveGroup(ROOT_GID); 
  66. } 
  67. } 
  68. } 

preloadClasses看起来很简单,但是实际上它有很多的类需要加载。可以查看一下/frameworks/base/preloaded-classes文件,这里面都是需要预加载的类。

接下来,分析一下preloadResources函数的源码:

 

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

接下来,是预加载OpenGL。源码如下:

 

 
  1. private static void preloadOpenGL() 
  2. { 
  3. if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) { 
  4. EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); 
  5. } 
  6. } 

启动system_server

现在我们要分析第三个关键点:startSystemServer。这个函数会创建java世界中系统Service所驻留的进程system_server,该进程是framework的核心。如何system_server挂掉,会导致zygote自杀。我们来看一下startSystemServer()实现源码。

  1. /** 
  2. * Prepare the arguments and fork for the system server process. 
  3. */ 
  4. private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException 
  5. { 
  6. long capabilities = posixCapabilitiesAsBits( 
  7. OsConstants.CAP_KILL, 
  8. OsConstants.CAP_NET_ADMIN, 
  9. OsConstants.CAP_NET_BIND_SERVICE, 
  10. OsConstants.CAP_NET_BROADCAST, 
  11. OsConstants.CAP_NET_RAW, 
  12. OsConstants.CAP_SYS_MODULE, 
  13. OsConstants.CAP_SYS_NICE, 
  14. OsConstants.CAP_SYS_RESOURCE, 
  15. OsConstants.CAP_SYS_TIME, 
  16. OsConstants.CAP_SYS_TTY_CONFIG 
  17. ); 
  18.  
  19. // 设置参数 
  20. String args[] = { 
  21. "--setuid=1000", 
  22. "--setgid=1000", 
  23. "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007", 
  24. "--capabilities=" + capabilities + "," + capabilities, 
  25. "--runtime-init", 
  26. "--nice-name=system_server", // 进程名为system_server 
  27. "com.android.server.SystemServer", 
  28. }; 
  29.  
  30. ZygoteConnection.Arguments parsedArgs = null; 
  31.  
  32. int pid; 
  33.  
  34. try { 
  35. parsedArgs = new ZygoteConnection.Arguments(args); 
  36. ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); 
  37. ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); 
  38.  
  39. /* Request to fork the system server process */ 
  40. pid = Zygote.forkSystemServer( 
  41. parsedArgs.uid, parsedArgs.gid, 
  42. parsedArgs.gids, 
  43. parsedArgs.debugFlags, 
  44. null, 
  45. parsedArgs.permittedCapabilities, 
  46. parsedArgs.effectiveCapabilities 
  47. ); 
  48. } catch (IllegalArgumentException ex) { 
  49. throw new RuntimeException(ex); 
  50. } 
  51.  
  52. /* For child process */ 
  53. if (pid == 0) { 
  54. handleSystemServerProcess(parsedArgs); 
  55. } 
  56.  
  57. return true; 
  58. } 

 

有求必应之等待请求——runSelectLoop

zygote从startSystemServer返回后,将进入第四个关键的函数:runSelectLoop。我们来看一下这个函数的实现:

 

 
  1. static final int GC_LOOP_COUNT = 10; 
  2. private static void runSelectLoop() throws MethodAndArgsCaller { 
  3. ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); 
  4. ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); 
  5. FileDescriptor[] fdArray = new FileDescriptor[4]; 
  6.  
  7. fds.add(sServerSocket.getFileDescriptor()); 
  8. peers.add(null); 
  9.  
  10. int loopCount = GC_LOOP_COUNT; 
  11. while (true) { 
  12. int index; 
  13. if (loopCount <= 0) { 
  14. gc(); 
  15. loopCount = GC_LOOP_COUNT; 
  16. } else { 
  17. loopCount --; 
  18. } 
  19.  
  20. try { 
  21. fdArray = fds.toArray(fdArray); 
  22. index = selectReadable(fdArray); 
  23. } catch(IOException ex) { 
  24. throw new RuntimeException("Error in select()", ex); 
  25. } 
  26.  
  27. if (index < 0) { 
  28. throw new RuntimeException("Error in select()"); 
  29. } else if (index == 0) { 
  30. ZygoteConnection newPeer = acceptCommandPeer(); 
  31. peers.add(newPeer); 
  32. } 
  33. } 
  34. } 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表