這篇文章主要介紹了詳細(xì)分析Android中實(shí)現(xiàn)Zygote的源碼,包括底層的C/C++代碼以及Java代碼部分入口,需要的朋友可以參考下
概述
在Android系統(tǒng)中,所有的應(yīng)用程序進(jìn)程,以及用來(lái)運(yùn)行系統(tǒng)關(guān)鍵服務(wù)的System進(jìn)程都是由zygote進(jìn)程負(fù)責(zé)創(chuàng)建的。因此,我們將它稱(chēng)為進(jìn)程孵化器。zygote進(jìn)程是通過(guò)復(fù)制自身的方式來(lái)創(chuàng)建System進(jìn)程和應(yīng)用程序進(jìn)程的。由于zygote進(jìn)程在啟動(dòng)時(shí)會(huì)在內(nèi)部創(chuàng)建一個(gè)虛擬機(jī)實(shí)例,因此,通過(guò)復(fù)制zygote進(jìn)程而得到的System進(jìn)程和應(yīng)用程序進(jìn)程可以快速地在內(nèi)部獲得一個(gè)虛擬機(jī)實(shí)例拷貝。
zygote進(jìn)程在啟動(dòng)完成之后,會(huì)馬上將System進(jìn)程啟動(dòng)起來(lái),以便它可以將系統(tǒng)的關(guān)鍵服務(wù)啟動(dòng)起來(lái)。下面我們將介紹zygote進(jìn)程的啟動(dòng)腳本,然后分析它和System進(jìn)程的啟動(dòng)過(guò)程。
zygote分析
zygote進(jìn)程的啟動(dòng)腳本如下:
- service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
- class main
- socket zygote stream 660 root system
- onrestart write /sys/android_power/request_state wake
- onrestart write /sys/power/state on
- onrestart restart media
- onrestart restart netd
解析配置文件
在我之前的一篇博客中已經(jīng)分析了init進(jìn)程是如何啟動(dòng)service服務(wù)了,需要了解的同學(xué)可以參考這篇文章:Android init進(jìn)程——
通過(guò)zygote服務(wù)的啟動(dòng)腳本,我們可以知道,zygote進(jìn)程的實(shí)際是二進(jìn)制文件app_process的調(diào)用,我們就從這個(gè)應(yīng)用程序的main函數(shù)入手去分析一下zygote進(jìn)程的啟動(dòng)過(guò)程,源碼如下(/frameworks/base/cmds/app_process/app_main.cpp):
- /**
- * 將-Xzygote加入到JavaVMOption中,返回/system/bin參數(shù)指向的下標(biāo)
- */
- int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
- {
- int i;
- for (i = 0; i < argc; i ++) {
- if (argv[i][0] != '-') {
- return i;
- }
- if (argv[i][1] == '-' && argv[i][2] == 0) {
- return i + 1;
- }
- JavaVMOption opt;
- memset(&opt, 0, sizeof(opt));
- opt.optionString = (char*)argv[i];
- mOptions.add(opt);
- }
- return i;
- }
- int main(int argc, char* const argv[])
- {
- // zygote call parameters
- // /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
- // These are global variables in ProcessState.cpp
- mArgC = argc;
- mArgV = argv;
- mArgLen = 0;
- for (int i = 0; i < argc; i ++) {
- mArgLen += strlen(argv[i]) + 1;
- }
- // 去除末尾的空格
- mArgLen--;
- AppRuntime runtime;
- const char* argv0 = argv[0];
- // Process command line arguments
- // ignore argv[0]
- argc --;
- argv ++;
- // Everything up tp '--' or first non '-' arg goes to the vm
- int i = runtime.addVmArguments(argc, argv);
- // Parse runtime arguments. Stop at first unrecognized option.
- bool zygote = false;
- bool startSystemServer = false;
- bool application = false;
- const char* parentDir = NULL;
- const char* niceName = NULL;
- const char* className = NULL;
- while (i < argc) {
- const char* arg = argv[i ++];
- if (!parentDir) {
- parentDir = arg;
- } else if (strcmp(arg, "--zygote") == 0) {
- zygote = true;
- niceName = "zygote";
- } else if (strcmp(arg, "--start-system-server") == 0) {
- startSystemServer = true;
- } else if (strcmp(arg, "--application") == 0) {
- application = true;
- } else if (strncmp(arg, "--nice-name=", 12)) {
- niceName = arg + 12;
- } else {
- className = arg;
- break;
- }
- }
- if (niceName && *niceName) {
- setArgv0(argv0, niceName);
- set_process_name(niceName);
- }
- runtime.mParentDir = parentDir;
- if (zygote) {
- // 進(jìn)入到AppRuntime的start函數(shù)
- runtime.start("com.android.internal.os.ZygoteInit",
- startSystemServer? "start-system-server" : "");
- } else if (className) {
- runtime.mClassName = className;
- runtime.mArgc = argc - i;
- runtime.mArgv = argv + i;
- runtime.start("com.android.internal.os.RuntimeInit", application ? "application" : "tool");
- } else {
- fprintf("stderr", "Error: no class name or --zygote supplied./n");
- app_usage();
- LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied");
- return 10;
- }
- }
在zygote的main函數(shù)中,通過(guò)AppRuntime runtime代碼創(chuàng)建了一個(gè)AppRuntime對(duì)象runtime,接下來(lái)Zygote進(jìn)程就是通過(guò)它來(lái)進(jìn)一步啟動(dòng)的。
init.rc中關(guān)于啟動(dòng)zygote命令中包含了–zygote參數(shù),所以在if(strcmp(arg, “–zygote”) == 0)判斷的時(shí)候,會(huì)將niceName賦值為”zygote”,然后通過(guò)set_process_name(niceName)函數(shù)將當(dāng)前進(jìn)程的名稱(chēng)設(shè)置為zygote。這也是為什么調(diào)用的腳本為/system/bin/app_process,而進(jìn)程名為zygote的原因。set_process_name函數(shù)的源碼如下(/system/core/libcutils/process_name.c):
- static const char* process_name = "unknown";
- void set_process_name(const char* new_name)
- {
- if (new_name == NULL) {
- return;
- }
- int len = strlen(new_name);
- char* copy = (char*)malloc(len + 1);
- strcpy(copy, new_name);
- process_name = (const char*) copy;
- }
從init.rc文件中關(guān)于zygote進(jìn)程的配置參數(shù)可知,Zygote進(jìn)程傳遞給應(yīng)用程序app_process的啟動(dòng)參數(shù)arg還包含一個(gè)”–start-system-server”選項(xiàng)。因此,在調(diào)用AppRuntime對(duì)象runtime的成員函數(shù)start時(shí),第二個(gè)參數(shù)為”start-system-server”,表示zygote進(jìn)程啟動(dòng)完成之后,需要將system進(jìn)程啟動(dòng)起來(lái)。
AppRuntime分析
AppRuntime類(lèi)的成員函數(shù)start是從父類(lèi)AndroidRuntime繼承下來(lái)的,因此,接下來(lái)我們就繼續(xù)分析AndroidRuntime類(lèi)的成員函數(shù)start的實(shí)現(xiàn),函數(shù)源碼位置:/frameworks/base/core/jni/AndroidRuntime.cpp:
- char* AndroidRuntime::toSlashClassName(const char* className)
- {
- char* result = strdup(className);
- for (char* cp = result; *cp != '/0'; cp ++) {
- if (*cp == '.') {
- *cp = '/';
- }
- }
- return result;
- }
- /**
- * Start the Android runtime. This involves starting the virtual machine
- * and calling the "static void main(String[] args)" method int the class
- * named by "className".
- *
- * 這兩個(gè)參數(shù)的值分別為:
- * const char* className = "com.android.internal.os.ZygoteInit";
- * const char* options = "start-system-server";
- */
- void AndroidRuntime::start(const char* className, const char* options)
- {
- ALOGD("/n>>>>> AndroidRuntime START %s <<<<<</n",
- className != NULL ? className : "(unknown)");
- /**
- * 'startSystemServer == true' means runtime is obsolete and not run from
- * init.rc anymore, so we print out the boot start event here.
- */
- if (strcmp(options, "start-system-server") == 0) {
- const int LOG_BOOT_PROGRESS_START = 3000;
- LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
- }
- // 設(shè)置ANDROID_ROOT環(huán)境變量
- const char* rootDir = getenv("ANDROID_ROOT");
- if (rootDir == NULL) {
- rootDir = "/system";
- if (!hasDir("/system")) {
- LOG_FATAL("No root directory specified, and /android dose not exist.");
- return;
- }
- setenv("ANDROID_ROOT", rootDir, 1);
- }
- JniInvocation jni_invocation;
- jni_invocation.Init(NULL);
- JNIEnv* env;
- // 1. 創(chuàng)建虛擬機(jī)
- if (startVm(&mJavaVM, &env) != 0) {
- return;
- }
- onVmCreated(env);
- // 2. 注冊(cè)JNI函數(shù)
- if (startReg(env) < 0) {
- ALOGE("Unable to register all android natives/n");
- return;
- }
- jclass stringClass;
- jobjectArray strArray;
- jstring classNameStr;
- jstring optionsStr;
- stringClass = env->FindClass("java/lang/String");
- assert(stringClass != NULL);
- // 創(chuàng)建一個(gè)有兩個(gè)元素的String數(shù)組,用Java代碼表示為:String[] strArray = new String[2];
- strArray = env->NewObjectArray(2, stringClass, NULL);
- assert(strArray != NULL);
- classNameStr = env->NewStringUTF(className);
- assert(classNameStr != NULL);
- // 設(shè)置第一個(gè)元素為"com.android.internal.os.ZygoteInit"
- env->SetObjectArrayElement(strArray, 0, classNameStr);
- optionsStr = env->NewStringUTF(options);
- // 設(shè)置第二個(gè)元素為"start-system-server"
- env->SetObjectArrayElement(strArray, 1, optionsStr);
- // 將字符串"com.android.internal.os.ZygoteInit"轉(zhuǎn)換為"com/android/internal/os/ZygoteInit"
- char* slashClassName = toSlashClassName(className);
- jclass startClass = env->FindClass(slashClassName);
- if (startClass == NULL) {
- ALOGE("JavaVM unable to locate class '%s'/n", slashClassName);
- } else {
- jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
- if (startMeth == NULL) {
- ALOGE("JavaVM unable to find main() in '%s/n'", className);
- } else {
- // 3.
- // 通過(guò)JNI調(diào)用java函數(shù),注意調(diào)用的是main函數(shù),所屬的類(lèi)是"com.android.internal.os.ZygoteInit".
- // 傳遞的參數(shù)是"com.android.internal.os.ZygoteInit true"
- env->CallStaticVoidMethod(startClass, startMeth, strArray);
- }
- }
- free(slashClassName);
- ALOGD("Shutting down VM/n");
- if (mJavaVM->DetachCurrentThread() != JNI_OK) {
- ALOGW("Warning: unable to detach main thread/n");
- }
- if (mJavaVM->DestoryJavaVM() != 0) {
- ALOGW("Warning: VM did not shut down cleanly/n");
- }
- }
上述代碼有幾處關(guān)鍵點(diǎn),分別是:
創(chuàng)建虛擬機(jī)。
注冊(cè)JNI函數(shù)。
進(jìn)入Java世界。
接下來(lái),我們分別分析這三個(gè)關(guān)鍵點(diǎn)。
創(chuàng)建虛擬機(jī)——startVm
startVm并沒(méi)有特別之處,就是調(diào)用JNI的虛擬機(jī)創(chuàng)建函數(shù),但是創(chuàng)建虛擬機(jī)時(shí)的一些參數(shù)卻是在startVm中確定的,其源碼如下:
- #define PROPERTY_VALUE_MAX 92
- /**
- * Start the Dalvik Virtual Machine.
- *
- * Various arguments, most determined by system properties, are passed in.
- * The "mOptions" vector is updated.
- *
- * Returns 0 on success.
- */
- int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIENV** pEnv)
- {
- int result = -1;
- JavaVMInitArgs initArgs;
- JavaVMOption opt;
- char propBuf[PROPERTY_VALUE_MAX];
- char stackTraceFileBuf[PROPERTY_VALUE_MAX];
- char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
- char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
- char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
- char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
- char heapsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
- char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
- char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
- char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
- char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
- char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX];
- char extraOptsBuf[PROPERTY_VALUE_MAX];
- char* stackTraceFile = NULL;
- bool checkJni = false;
- bool checkDexSum = false;
- bool logStdio = false;
- enum {
- KEMDefault,
- KEMIntPortable,
- KEMIntFast,
- KEMJitCompiler,
- } executionMode = KEMDefault;
- /**
- * 這段代碼是用了設(shè)置JNI_check選項(xiàng)的。JNI_check指的是Native層調(diào)用JNI函數(shù)時(shí),系統(tǒng)所做的一些檢查動(dòng)作。
- * 這個(gè)選項(xiàng)雖然能增加可靠性,但是還有一些副作用:
- * 1. 因?yàn)闄z查工作比較耗時(shí),所以會(huì)影響系統(tǒng)運(yùn)行速度。
- * 2. 有些檢查工作比較耗時(shí),一旦出錯(cuò),整個(gè)進(jìn)程會(huì)abort。
- * 所以,JNI_check選項(xiàng)一般只在eng版本設(shè)置。
- */
- property_get("dalvik.vm.checkjni", propBuf, "");
- if (strcmp(propBuf, "true") == 0) {
- checkJni = true;
- } else if (strcmp(propBuf, "false") != 0) {
- property_get("ro.kernel.android.checkjni", propBuf, "");
- if (propBuf[0] == '1') {
- checkJni = true;
- }
- }
- property_get("dalvik.vm.execution-mode", propBuf, "");
- if (strcmp(propBuf, "int:portable") == 0) {
- executionMode = KEMIntPortable;
- } else if (strcmp(propBuf, "int:fast") == 0) {
- executionMode = KEMIntFast;
- } else if (strcmp(propBuf, "int:jit") == 0) {
- executionMode = KEMJitCompiler;
- }
- // ... 省略大部分參數(shù)設(shè)置
- /**
- * 設(shè)置虛擬機(jī)的heapsize,默認(rèn)為16m。絕大多數(shù)廠商都會(huì)在build.prop文件里修改這個(gè)屬性,一般是256m。
- * heapsize不能設(shè)置得過(guò)小,否則在操作大尺寸的圖片時(shí)無(wú)法分配所需的內(nèi)存。
- */
- strcpy(heapsizeOptsBuf, "-Xmx");
- property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
- opt.optionString = heapsizeOptsBuf;
- mOptions.add(opt);
- // ......
- if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
- ALOGE("JNI_CreateJavaVM failed/n");
- goto bail;
- }
- result = 0;
- bail:
- free(stackTraceFile);
- return result;
- }
更多虛擬機(jī)參數(shù)的設(shè)置,我這里就不做特殊說(shuō)明了,大家感興趣可以自行g(shù)oogle。(ps:因?yàn)槲也惶摂M機(jī)這一塊…)
注冊(cè)JNI函數(shù)——startReg
上面講了如何創(chuàng)建虛擬機(jī),接下來(lái)需要給這個(gè)虛擬機(jī)注冊(cè)一些JNI函數(shù)。正是因?yàn)楹罄m(xù)的Java世界用到的一些函數(shù)是采用native方式實(shí)現(xiàn)的,所以才必須提前注冊(cè)這些函數(shù)。
接下來(lái),我們來(lái)看一下startReg函數(shù)的源碼實(shí)現(xiàn):
- int AndroidRuntime::startReg(JNIEnv* env)
- {
- // 設(shè)置Thread類(lèi)的線程創(chuàng)建函數(shù)為javaCreateThreadEtc
- androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
- ALOGV("--- registering native functions ---/n");
- env->PushLocalFrame(200);
- if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
- env->PopLocalFrame(NULL);
- return -1;
- }
- env->PopLocalFrame(NULL);
- return 0;
- }
關(guān)鍵是需要注冊(cè)JNI函數(shù),具體實(shí)現(xiàn)是由register_jni_procs函數(shù)實(shí)現(xiàn)的,我們來(lái)看一下這個(gè)函數(shù)的具體實(shí)現(xiàn)(/frameworks/base/core/jni/AndroidRuntime.cpp):
- static int register_jni_procs(const RegJNIRec array[], size_T count, JNIEnv* env)
- {
- for (size_t i = 0; i < count; i ++) {
- if (array[i].mProc(env) < 0) {
- #ifndef NDEBUG
- ALOGD("------!!! %s failed to load/n", array[i].mName);
- #endif
- return -1;
- }
- }
- return 0;
- }
通過(guò)源碼,我們可以看到,register_jni_procs只是對(duì)array數(shù)組的mProc函數(shù)的封裝,而array數(shù)組指向的是gRegJNI數(shù)組,我們來(lái)看一下這個(gè)數(shù)組的實(shí)現(xiàn):
- static const RegJNIRec gRegJNI[] = {
- REG_JNI(register_android_debug_JNITest),
- REG_JNI(register_com_android_internal_os_RuntimeInit),
- REG_JNI(register_android_os_SystemClock),
- REG_JNI(register_android_util_EventLog),
- REG_JNI(register_android_util_Log),
- REG_JNI(register_android_util_FloatMath),
- REG_JNI(register_android_text_format_Time),
- REG_JNI(register_android_content_AssetManager),
- REG_JNI(register_android_content_StringBlock),
- REG_JNI(register_android_content_XmlBlock),
- REG_JNI(register_android_emoji_EmojiFactory),
- REG_JNI(register_android_text_AndroidCharacter),
- REG_JNI(register_android_text_AndroidBidi),
- REG_JNI(register_android_view_InputDevice),
- REG_JNI(register_android_view_KeyCharacterMap),
- REG_JNI(register_android_os_Process),
- REG_JNI(register_android_os_SystemProperties),
- REG_JNI(register_android_os_Binder),
- REG_JNI(register_android_os_Parcel),
- REG_JNI(register_android_view_DisplayEventReceiver),
- REG_JNI(register_android_nio_utils),
- REG_JNI(register_android_graphics_Graphics),
- REG_JNI(register_android_view_GraphicBuffer),
- REG_JNI(register_android_view_GLES20DisplayList),
- REG_JNI(register_android_view_GLES20Canvas),
- REG_JNI(register_android_view_HardwareRenderer),
- REG_JNI(register_android_view_Surface),
- REG_JNI(register_android_view_SurfaceControl),
- REG_JNI(register_android_view_SurfaceSession),
- REG_JNI(register_android_view_TextureView),
- REG_JNI(register_com_google_android_gles_jni_EGLImpl),
- REG_JNI(register_com_google_android_gles_jni_GLImpl),
- REG_JNI(register_android_opengl_jni_EGL14),
- REG_JNI(register_android_opengl_jni_EGLExt),
- REG_JNI(register_android_opengl_jni_GLES10),
- REG_JNI(register_android_opengl_jni_GLES10Ext),
- REG_JNI(register_android_opengl_jni_GLES11),
- REG_JNI(register_android_opengl_jni_GLES11Ext),
- REG_JNI(register_android_opengl_jni_GLES20),
- REG_JNI(register_android_opengl_jni_GLES30),
- REG_JNI(register_android_graphics_Bitmap),
- REG_JNI(register_android_graphics_BitmapFactory),
- REG_JNI(register_android_graphics_BitmapRegionDecoder),
- REG_JNI(register_android_graphics_Camera),
- REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
- REG_JNI(register_android_graphics_Canvas),
- REG_JNI(register_android_graphics_ColorFilter),
- REG_JNI(register_android_graphics_DrawFilter),
- REG_JNI(register_android_graphics_Interpolator),
- REG_JNI(register_android_graphics_LayerRasterizer),
- REG_JNI(register_android_graphics_MaskFilter),
- REG_JNI(register_android_graphics_Matrix),
- REG_JNI(register_android_graphics_Movie),
- REG_JNI(register_android_graphics_NinePatch),
- REG_JNI(register_android_graphics_Paint),
- REG_JNI(register_android_graphics_Path),
- REG_JNI(register_android_graphics_PathMeasure),
- REG_JNI(register_android_graphics_PathEffect),
- REG_JNI(register_android_graphics_Picture),
- REG_JNI(register_android_graphics_PorterDuff),
- REG_JNI(register_android_graphics_Rasterizer),
- REG_JNI(register_android_graphics_Region),
- REG_JNI(register_android_graphics_Shader),
- REG_JNI(register_android_graphics_SurfaceTexture),
- REG_JNI(register_android_graphics_Typeface),
- REG_JNI(register_android_graphics_Xfermode),
- REG_JNI(register_android_graphics_YuvImage),
- REG_JNI(register_android_graphics_pdf_PdfDocument),
- REG_JNI(register_android_database_CursorWindow),
- REG_JNI(register_android_database_SQLiteConnection),
- REG_JNI(register_android_database_SQLiteGlobal),
- REG_JNI(register_android_database_SQLiteDebug),
- REG_JNI(register_android_os_Debug),
- REG_JNI(register_android_os_FileObserver),
- REG_JNI(register_android_os_MessageQueue),
- REG_JNI(register_android_os_SELinux),
- REG_JNI(register_android_os_Trace),
- REG_JNI(register_android_os_UEventObserver),
- REG_JNI(register_android_net_LocalSocketImpl),
- REG_JNI(register_android_net_NetworkUtils),
- REG_JNI(register_android_net_TrafficStats),
- REG_JNI(register_android_net_wifi_WifiNative),
- REG_JNI(register_android_os_MemoryFile),
- REG_JNI(register_com_android_internal_os_ZygoteInit),
- REG_JNI(register_android_hardware_Camera),
- REG_JNI(register_android_hardware_camera2_CameraMetadata),
- REG_JNI(register_android_hardware_SensorManager),
- REG_JNI(register_android_hardware_SerialPort),
- REG_JNI(register_android_hardware_UsbDevice),
- REG_JNI(register_android_hardware_UsbDeviceConnection),
- REG_JNI(register_android_hardware_UsbRequest),
- REG_JNI(register_android_media_AudioRecord),
- REG_JNI(register_android_media_AudioSystem),
- REG_JNI(register_android_media_AudioTrack),
- REG_JNI(register_android_media_JetPlayer),
- REG_JNI(register_android_media_RemoteDisplay),
- REG_JNI(register_android_media_ToneGenerator),
- REG_JNI(register_android_opengl_classes),
- REG_JNI(register_android_server_NetworkManagementSocketTagger),
- REG_JNI(register_android_server_Watchdog),
- REG_JNI(register_android_ddm_DdmHandleNativeHeap),
- REG_JNI(register_android_backup_BackupDataInput),
- REG_JNI(register_android_backup_BackupDataOutput),
- REG_JNI(register_android_backup_FileBackupHelperBase),
- REG_JNI(register_android_backup_BackupHelperDispatcher),
- REG_JNI(register_android_app_backup_FullBackup),
- REG_JNI(register_android_app_ActivityThread),
- REG_JNI(register_android_app_NativeActivity),
- REG_JNI(register_android_view_InputChannel),
- REG_JNI(register_android_view_InputEventReceiver),
- REG_JNI(register_android_view_InputEventSender),
- REG_JNI(register_android_view_InputQueue),
- REG_JNI(register_android_view_KeyEvent),
- REG_JNI(register_android_view_MotionEvent),
- REG_JNI(register_android_view_PointerIcon),
- REG_JNI(register_android_view_VelocityTracker),
- REG_JNI(register_android_content_res_ObbScanner),
- REG_JNI(register_android_content_res_Configuration),
- REG_JNI(register_android_animation_PropertyValuesHolder),
- REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
- REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
- };
- #ifdef NDEBUG
- #define REG_JNI(name) {name}
- struct RegJNIRec {
- int (*mProc)(JNIEnv*);
- };
- #else
- #define REG_JNI(name) {name, #name}
- struct RegJNIRec {
- int (*mProc)(JNIEnv*);
- const char* mName;
- };
- #endif
可以看到,REG_JNI是一個(gè)宏,宏里面包括的就是那個(gè)參數(shù)為JNIEnv*,返回值為int的函數(shù)指針mProc,我們以register_android_debug_JNITest為例,源碼位置為/frameworks/base/core/jni/android_debug_JNITest.cpp:
- #define NELEM(x) (sizeof(x)/sizeof(*(x)))
- int register_android_debug_JNITest(JNIEnv* env)
- {
- return jniRegisterNativeMethods(env, "android/debug/JNITest", gMethods, NELEM(gMethods));
- }
可以看到,mProc其實(shí)就是為Java類(lèi)注冊(cè)JNI函數(shù)。
進(jìn)入JAVA世界
可以看到CallStaticVoidMethod最終將調(diào)用com.android.internal.os.ZygoteInit的main函數(shù),下面就來(lái)看一下這個(gè)Java世界的入口函數(shù)。源碼位置:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,源碼如下:
- public static void main(String argv[])
- {
- try {
- SamplingProfilerIntegration.start();
- // 1. 注冊(cè)zygote用的socket
- registerZygoteSocket();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
- // 2. 預(yù)加載類(lèi)和資源
- preload();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());
- SamplingProfilerIntegration.writeZygoteSnapshot();
- // 強(qiáng)制執(zhí)行一次垃圾收集
- gc();
- Trace.setTracingEnabled(false);
- if (argv.length != 2) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- if (argv[1].equals("start-system-server")) {
- // 3. 啟動(dòng)system-server
- startSystemServer();
- } else if (!argv[1].equals("")) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- Log.i(TAG, "Accepting command socket connections");
- // 4. 進(jìn)入請(qǐng)求應(yīng)答模式
- runSelectLoop();
- closeServerSocket();
- } catch(MethodAndArgsCaller caller) {
- caller.run();
- } catch(RuntimeException ex) {
- Log.e(TAG, "Zygote died with exception", ex);
- closeServerSocket();
- throw ex;
- }
- }
上述代碼中有5個(gè)重要的點(diǎn),我已經(jīng)通過(guò)標(biāo)號(hào)標(biāo)記出來(lái)了,接下來(lái)我們分別分析一下這5點(diǎn)函數(shù)的具體實(shí)現(xiàn)。
建立IPC通信服務(wù)端——registerZygoteSocket
zygote及系統(tǒng)中其他程序的通信沒(méi)有使用Binder,而是采用了基于AF_UNIX類(lèi)型的socket。registerZygoteSocket函數(shù)的使命正是建立這個(gè)Socket,實(shí)現(xiàn)代碼如下:
- private static void registerZygoteSocket()
- {
- if (sServerSocket == null) {
- int fileDesc;
- try {
- String env = System.getenv(ANDROID_SOCKET_ENV);
- fileDesc = Integer.parseInt(env);
- } catch (RuntimeException ex) {
- throw new RuntimeException(ANDROID_SOCKET_ENV + " unset or invalid", ex);
- }
- try {
- sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc));
- } catch(IOException ex) {
- throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex);
- }
- }
- }
- public class LocalServerSocket {
- private final LocalSocketImpl impl;
- private final LocalSocketAddress localAddress;
- private static final int LISTEN_BACKLOG = 50;
- /**
- * Create a LocalServerSocket from a file descriptor that's already
- * been created and bound. listen() will be called immediately on it.
- * Used for cases where file descriptors are passed in via environment
- * variables.
- */
- public LocalServerSocket(FileDescriptor fd) throws IOException {
- impl = new LocalSocketImpl(fd);
- impl.listen(LISTEN_BACKLOG);
- }
- }
registerZygoteSocket很簡(jiǎn)單,就是創(chuàng)建一個(gè)服務(wù)端的socket。
預(yù)加載類(lèi)和資源——preload
我們先來(lái)看一下preload函數(shù)實(shí)現(xiàn):
- static void preload()
- {
- preloadClasses();
- preloadResources();
- preloadOpenGL();
- }
preload函數(shù)里面分別調(diào)用了三個(gè)預(yù)加載函數(shù),我們分別來(lái)分析一下這幾個(gè)函數(shù)的實(shí)現(xiàn)。
首先是preloadClasses,函數(shù)實(shí)現(xiàn)如下:
- private static final int UNPRIVILEGED_UID = 9999;
- private static final int UNPRIVILEGED_GID = 9999;
- private static final int ROOT_UID = 0;
- private static final int ROOT_GID = 0;
- private static void preloadClasses()
- {
- final VMRuntime runtime = VMRuntime.getRuntime();
- InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(PRELOADED_CLASSES);
- if (is == null) {
- Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
- } else {
- Log.i(TAG, "Preloading classes...");
- long startTime = SystemClock.uptimeMillis();
- setEffectiveGroup(UNPRIVILEGED_GID);
- setEffectiveGroup(UNPRIVILEGED_UID);
- float defaultUtilization = runtime.getTargetHeapUtilization();
- runtime.setTargetHeapUtilization(0.8f);
- System.gc();
- runtime.runFinalizationSync();
- Debug.startAllocCounting();
- try {
- // 創(chuàng)建一個(gè)緩沖區(qū)為256字符的輸入流
- BufferedReader br = new BufferdReader(new InputStreamReader(is), 256);
- int count = 0;
- String line;
- while ((line = br.readLine()) != null) {
- // skip comments and blank lines.
- line = line.trim();
- if (line.startsWith("#") || line.equals("")) {
- continue;
- }
- try {
- if (false) {
- Log.v(TAG, "Preloading " + line + "...");
- }
- Class.forName(line);
- count ++;
- } catch (ClassNotFoundException e) {
- Log.w(TAG, "Class not found for preloading: " + line);
- } catch (UnsatisfiedLinkError e) {
- Log.w(TAG, "Problem preloading " + line + ": " + e);
- } catch(Throwable t) {
- Log.e(TAG, "Error preloading " + line + ".", t);
- }
- }
- Log.i(TAG, "...preloaded " + count + " classes in " + (SystemClock.uptimeMillis()-startTime) + "ms.");
- } catch (IOException e) {
- Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
- } finally {
- IoUtils.closeQuietly(is);
- runtime.setTargetHeapUtilization(defaultUtilization);
- runtime.preloadDexCaches();
- Debug.stopAllocCounting();
- setEffectiveUser(ROOT_UID);
- setEffectiveGroup(ROOT_GID);
- }
- }
- }
preloadClasses看起來(lái)很簡(jiǎn)單,但是實(shí)際上它有很多的類(lèi)需要加載。可以查看一下/frameworks/base/preloaded-classes文件,這里面都是需要預(yù)加載的類(lèi)。
接下來(lái),分析一下preloadResources函數(shù)的源碼:
- private static final boolean PRELOAD_RESOURCES = true;
- private static void preloadResources()
- {
- final VMRuntime runtime = VMRuntime.getRuntime();
- Debug.startAllocCounting();
- try {
- System.gc();
- runtime.runFinalizationSync();
- mResources = Resources.getSystem();
- mResources.startPreloading();
- if (PRELOAD_RESOURCES) {
- Log.i(TAG, "Preloading resources...");
- long startTime = SystemClock.uptimeMillis();
- TypedArray ar = mResources.obtainTypedArray(com.android.internal.R.array.preloaded_drawables);
- int N = preloadDrawables(runtime, ar);
- ar.recycle();
- Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis()-startTime) + "ms.");
- startTime = SystemClock.uptimeMillis();
- ar = mResources.obtainTypedArray(com.android.internal.R.array.preloaded_color_state_lists);
- N = preloadColorstateLists(runtime, ar);
- ar.recycle();
- Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms.");
- }
- mResources.finishPreloading();
- } catch (RuntimeException e) {
- Log.w(TAG, "Failure preloading resources", e);
- } finally {
- Debug.stopAllocCounting();
- }
- }
接下來(lái),是預(yù)加載OpenGL。源碼如下:
- private static void preloadOpenGL()
- {
- if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) {
- EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
- }
- }
啟動(dòng)system_server
現(xiàn)在我們要分析第三個(gè)關(guān)鍵點(diǎn):startSystemServer。這個(gè)函數(shù)會(huì)創(chuàng)建java世界中系統(tǒng)Service所駐留的進(jìn)程system_server,該進(jìn)程是framework的核心。如何system_server掛掉,會(huì)導(dǎo)致zygote自殺。我們來(lái)看一下startSystemServer()實(shí)現(xiàn)源碼。
- /**
- * Prepare the arguments and fork for the system server process.
- */
- private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException
- {
- long capabilities = posixCapabilitiesAsBits(
- OsConstants.CAP_KILL,
- OsConstants.CAP_NET_ADMIN,
- OsConstants.CAP_NET_BIND_SERVICE,
- OsConstants.CAP_NET_BROADCAST,
- OsConstants.CAP_NET_RAW,
- OsConstants.CAP_SYS_MODULE,
- OsConstants.CAP_SYS_NICE,
- OsConstants.CAP_SYS_RESOURCE,
- OsConstants.CAP_SYS_TIME,
- OsConstants.CAP_SYS_TTY_CONFIG
- );
- // 設(shè)置參數(shù)
- String args[] = {
- "--setuid=1000",
- "--setgid=1000",
- "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
- "--capabilities=" + capabilities + "," + capabilities,
- "--runtime-init",
- "--nice-name=system_server", // 進(jìn)程名為system_server
- "com.android.server.SystemServer",
- };
- ZygoteConnection.Arguments parsedArgs = null;
- int pid;
- try {
- parsedArgs = new ZygoteConnection.Arguments(args);
- ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
- ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
- /* Request to fork the system server process */
- pid = Zygote.forkSystemServer(
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids,
- parsedArgs.debugFlags,
- null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities
- );
- } catch (IllegalArgumentException ex) {
- throw new RuntimeException(ex);
- }
- /* For child process */
- if (pid == 0) {
- handleSystemServerProcess(parsedArgs);
- }
- return true;
- }
|
|
有求必應(yīng)之等待請(qǐng)求——runSelectLoop
zygote從startSystemServer返回后,將進(jìn)入第四個(gè)關(guān)鍵的函數(shù):runSelectLoop。我們來(lái)看一下這個(gè)函數(shù)的實(shí)現(xiàn):
- static final int GC_LOOP_COUNT = 10;
- private static void runSelectLoop() throws MethodAndArgsCaller {
- ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
- ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
- FileDescriptor[] fdArray = new FileDescriptor[4];
- fds.add(sServerSocket.getFileDescriptor());
- peers.add(null);
- int loopCount = GC_LOOP_COUNT;
- while (true) {
- int index;
- if (loopCount <= 0) {
- gc();
- loopCount = GC_LOOP_COUNT;
- } else {
- loopCount --;
- }
- try {
- fdArray = fds.toArray(fdArray);
- index = selectReadable(fdArray);
- } catch(IOException ex) {
- throw new RuntimeException("Error in select()", ex);
- }
- if (index < 0) {
- throw new RuntimeException("Error in select()");
- } else if (index == 0) {
- ZygoteConnection newPeer = acceptCommandPeer();
- peers.add(newPeer);
- }
- }
- }
新聞熱點(diǎn)
疑難解答