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

在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. if (new_name == NULL) { 
  4. return
  5.  
  6. int len = strlen(new_name); 
  7. char* copy = (char*)malloc(len + 1); 
  8. strcpy(copy, new_name); 
  9. process_name = (const char*) copy; 

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

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

创建虚拟机。

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

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

注册JNI函数——startReg

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

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

 

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

关键是需要注册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. for (size_t i = 0; i < count; i ++) { 
  3. if (array[i].mProc(env) < 0) { 
  4. #ifndef NDEBUG 
  5. ALOGD("------!!! %s failed to load/n", array[i].mName); 
  6. #endif 
  7. return -1; 
  8.  
  9. return 0; 

通过源码,我们可以看到,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. return jniRegisterNativeMethods(env, "android/debug/JNITest", gMethods, NELEM(gMethods)); 

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

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

建立IPC通信服务端——registerZygoteSocket

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

 

 
  1. private static void registerZygoteSocket() 
  2. if (sServerSocket == null) { 
  3. int fileDesc; 
  4. try { 
  5. String env = System.getenv(ANDROID_SOCKET_ENV); 
  6. fileDesc = Integer.parseInt(env); 
  7. catch (RuntimeException ex) { 
  8. throw new RuntimeException(ANDROID_SOCKET_ENV + " unset or invalid", ex); 
  9.  
  10. try {  
  11. sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc)); 
  12. catch(IOException ex) {  
  13. throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex); 
  14.  
  15. public class LocalServerSocket { 
  16. private final LocalSocketImpl impl; 
  17. private final LocalSocketAddress localAddress; 
  18.  
  19. private static final int LISTEN_BACKLOG = 50; 
  20.  
  21. /** 
  22. * Create a LocalServerSocket from a file descriptor that's already 
  23. * been created and bound. listen() will be called immediately on it. 
  24. * Used for cases where file descriptors are passed in via environment 
  25. * variables. 
  26. */ 
  27. public LocalServerSocket(FileDescriptor fd) throws IOException { 
  28. impl = new LocalSocketImpl(fd); 
  29. impl.listen(LISTEN_BACKLOG); 
  30. localAddress = impl.getSockAddress(); 

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

预加载类和资源——preload

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

 

 
  1. static void preload() 
  2. preloadClasses(); 
  3. preloadResources(); 
  4. preloadOpenGL(); 

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. final VMRuntime runtime = VMRuntime.getRuntime(); 
  9.  
  10. InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(PRELOADED_CLASSES); 
  11. if (is == null) { 
  12. Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + "."); 
  13. else { 
  14. Log.i(TAG, "Preloading classes..."); 
  15. long startTime = SystemClock.uptimeMillis(); 
  16.  
  17. setEffectiveGroup(UNPRIVILEGED_GID); 
  18. setEffectiveGroup(UNPRIVILEGED_UID); 
  19.  
  20. float defaultUtilization = runtime.getTargetHeapUtilization(); 
  21. runtime.setTargetHeapUtilization(0.8f); 
  22.  
  23. System.gc(); 
  24. runtime.runFinalizationSync(); 
  25. Debug.startAllocCounting(); 
  26.  
  27. try { 
  28. // 创建一个缓冲区为256字符的输入流 
  29. BufferedReader br = new BufferdReader(new InputStreamReader(is), 256); 
  30. int count = 0; 
  31. String line; 
  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. try { 
  39. if (false) { 
  40. Log.v(TAG, "Preloading " + line + "..."); 
  41. Class.forName(line); 
  42. count ++; 
  43. catch (ClassNotFoundException e) { 
  44. Log.w(TAG, "Class not found for preloading: " + line); 
  45. catch (UnsatisfiedLinkError e) { 
  46. Log.w(TAG, "Problem preloading " + line + ": " + e); 
  47. catch(Throwable t) { 
  48. Log.e(TAG, "Error preloading " + line + ".", t); 
  49. Log.i(TAG, "...preloaded " + count + " classes in " + (SystemClock.uptimeMillis()-startTime) + "ms."); 
  50. catch (IOException e) { 
  51. Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e); 
  52. finally { 
  53. IoUtils.closeQuietly(is); 
  54. runtime.setTargetHeapUtilization(defaultUtilization); 
  55.  
  56. runtime.preloadDexCaches(); 
  57. Debug.stopAllocCounting(); 
  58.  
  59. setEffectiveUser(ROOT_UID); 
  60. setEffectiveGroup(ROOT_GID); 

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

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

 

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

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

 

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

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

 

有求必应之等待请求——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. try { 
  20. fdArray = fds.toArray(fdArray); 
  21. index = selectReadable(fdArray); 
  22. catch(IOException ex) { 
  23. throw new RuntimeException("Error in select()", ex); 
  24.  
  25. if (index < 0) { 
  26. throw new RuntimeException("Error in select()"); 
  27. else if (index == 0) { 
  28. ZygoteConnection newPeer = acceptCommandPeer(); 
  29. peers.add(newPeer); 

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