亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > 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); 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人免费91av在线| 国产视频精品自拍| 亚洲护士老师的毛茸茸最新章节| 日本电影亚洲天堂| 91在线直播亚洲| 在线播放精品一区二区三区| 91夜夜揉人人捏人人添红杏| 国产欧美 在线欧美| 亚洲精品免费网站| 在线观看国产成人av片| 2019最新中文字幕| 中文字幕一区二区三区电影| 一区二区国产精品视频| 欧美日本亚洲视频| 中文字幕亚洲无线码在线一区| 亚洲xxxx在线| 精品福利在线视频| 日韩精品999| 欧美日韩999| 欧美日韩亚洲国产一区| 欧美乱大交xxxxx| 久久久久久网址| 亚洲成人久久一区| 亚洲自拍欧美色图| 欧美黑人巨大精品一区二区| 亚洲精品久久在线| 欧美理论电影在线播放| 国产精品嫩草视频| 日韩精品视频免费在线观看| 久久91精品国产91久久久| 国产视频精品久久久| 日韩中文字幕在线| 欧美日韩国产成人在线| 久久影院资源站| 91久久嫩草影院一区二区| 亚洲最大福利网站| 91久久国产精品91久久性色| 日韩视频免费大全中文字幕| 夜夜嗨av一区二区三区免费区| 国产999在线| 欧美人在线观看| 欧美视频一二三| 久久亚洲精品一区二区| 亚洲成人亚洲激情| 91sa在线看| 欧美黑人极品猛少妇色xxxxx| 亚洲精品久久久久国产| 高跟丝袜欧美一区| 国产精品久久久久久久久久久久久| 中文字幕不卡在线视频极品| 亚洲欧美日韩第一区| 国产精品久久久久久网站| 国产69精品久久久久9| 国产精品三级在线| 91精品国产777在线观看| 亚洲女人天堂av| 日韩在线小视频| 91视频8mav| 成人免费观看a| 欧美日韩亚洲精品一区二区三区| 欧美性极品少妇精品网站| 国产91对白在线播放| 国产91色在线播放| 亚洲影院污污.| 久久久www成人免费精品张筱雨| www国产亚洲精品久久网站| www国产精品视频| 精品一区二区亚洲| 欧美乱人伦中文字幕在线| 日韩在线视频免费观看高清中文| 亚洲欧洲偷拍精品| 欧美激情a∨在线视频播放| 午夜精品视频在线| 日韩欧美精品在线观看| 欧美精品一区二区三区国产精品| 欧美做受高潮电影o| 在线日韩av观看| 亚洲精品乱码久久久久久金桔影视| 日韩av在线一区| 久久九九全国免费精品观看| 亚洲国产精久久久久久| 国产成+人+综合+亚洲欧美丁香花| 日韩av综合网站| 97久久精品国产| 国产a∨精品一区二区三区不卡| 国a精品视频大全| 色综合色综合久久综合频道88| 国产精品久久久亚洲| 日韩久久免费视频| 日韩精品视频在线免费观看| 亚州欧美日韩中文视频| 日本久久久久亚洲中字幕| 欧美亚洲在线观看| 亚洲国产精品悠悠久久琪琪| 亚洲午夜精品视频| 性欧美办公室18xxxxhd| 26uuu亚洲伊人春色| xxav国产精品美女主播| 国产日本欧美在线观看| 97精品在线视频| 欧美日韩激情小视频| 国产精品久久久久久久久男| 欧美在线视频一区二区| 国产精品久久久久久影视| 深夜精品寂寞黄网站在线观看| 欧美日韩成人网| 日韩经典中文字幕| 欧美综合在线观看| 5566日本婷婷色中文字幕97| 国产精品www网站| 亚洲国产欧美日韩精品| 亚洲自拍中文字幕| 国产人妖伪娘一区91| 精品美女久久久久久免费| 久久综合五月天| 精品久久久久久国产| 成人av番号网| 欧美一级成年大片在线观看| 在线视频日韩精品| 国产成人免费av电影| 久久99国产综合精品女同| 亚洲成人动漫在线播放| 欧美激情按摩在线| 播播国产欧美激情| 九九精品视频在线观看| 九九热视频这里只有精品| 国产精品99久久久久久久久| 久久全国免费视频| 欧美最猛性xxxx| 欧美日韩加勒比精品一区| 国产精品视频午夜| 国产精品久久久久影院日本| 亚洲香蕉在线观看| 成人黄在线观看| 亚洲国产精彩中文乱码av在线播放| 91精品国产色综合久久不卡98口| 97高清免费视频| 亚洲国产精品999| 久青草国产97香蕉在线视频| 国产精品视频免费在线观看| 大桥未久av一区二区三区| 性色av一区二区三区免费| 欧美精品在线第一页| 成人激情春色网| 国产精品日本精品| 欧美国产日产韩国视频| 日本亚洲欧洲色| 日韩视频第一页| 在线国产精品视频| 国产精品丝袜白浆摸在线| 日韩亚洲欧美中文在线| 欧美精品在线播放| 欧美精品一区二区免费| 国产精品国模在线| 韩国三级日本三级少妇99| 久热国产精品视频| 精品国产乱码久久久久久虫虫漫画| 午夜精品久久17c| 精品久久久香蕉免费精品视频| 精品自拍视频在线观看| 精品久久久久久久久久| 欧美成人性生活| 精品亚洲国产成av人片传媒| 亚洲国产精品女人久久久|