在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,zygote和system_server分别是Java世界的半边天,任何一个进程的死亡都会导致Java崩溃。
zygote本身是Native应用程序,与驱动内核无关。zygote最初的名字叫“app_process”,这个名字在Android.mk文件中指定,但在运行过程中被替换为"zygote"。
我们知道,Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中:
1.system/core/rootdir/init.rc:
-
- service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
-
- socket zygote stream 666
- critical
- onrestart write /sys/android_power/request_state wake
- onrestart write /sys/power/state on
- onrestart restart media
- onrestart restart netd
- onrestart restart mlistener
2.App_main.cpp
- int main(int argc, const char* const argv[])
- {
-
-
-
-
- mArgC = argc;
- mArgV = argv;
-
- mArgLen = 0;
- for (int i=0; i<argc; i++) {
- mArgLen += strlen(argv[i]) + 1;
- }
- mArgLen--;
-
- AppRuntime runtime;
- const char *arg;
- const char *argv0;
-
- argv0 = argv[0];
-
-
-
- argc--;
- argv++;
-
-
-
- int i = runtime.addVmArguments(argc, argv);
-
-
- if (i < argc) {
- runtime.mParentDir = argv[i++];
- }
-
-
- if (i < argc) {
- arg = argv[i++];
-
- if (0 == strcmp("--zygote", arg)) {
-
- bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false;
-
- setArgv0(argv0, "zygote");
-
- set_process_name("zygote");
-
- doLastShutDownCheck();
-
- runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
- } else {
- set_process_name(argv0);
-
- runtime.mClassName = arg;
-
-
- runtime.mArgC = argc-i;
- runtime.mArgV = argv+i;
-
- LOGV("App process is starting with pid=%d, class=%s.\n",
- getpid(), runtime.getClassName());
- runtime.start();
- }
- } else {
- LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
- fprintf(stderr, "Error: no class name or --zygote supplied.\n");
- app_usage();
- return 10;
- }
- }
这个函数的主要作用就是创建一个AppRuntime变量,然后调用它的start成员函数。AppRuntime类的声明和实现在App_main.cpp中,派生于AndroidRuntime类
3.AndroidRuntime.cpp
- void AndroidRuntime::start(const char* className, const bool startSystemServer)
- {
-
-
- LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",className != NULL ? className : "(unknown)");
- char* slashClassName = NULL;
- char* cp;
- JNIEnv* env;
-
- blockSigpipe();
-
-
-
-
-
- if (startSystemServer) {
-
- const int LOG_BOOT_PROGRESS_START = 3000;
- LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
- }
-
- const char* rootDir = getenv("ANDROID_ROOT");
- if (rootDir == NULL) {
- rootDir = "/system";
- if (!hasDir("/system")) {
- LOG_FATAL("No root directory specified, and /android does not exist.");
- goto bail;
- }
- setenv("ANDROID_ROOT", rootDir, 1);
- }
-
-
-
-
-
- if (startVm(&mJavaVM, &env) != 0)
- goto bail;
-
-
-
-
- if (startReg(env) < 0) {
- LOGE("Unable to register all android natives\n");
- goto bail;
- }
-
-
-
-
-
-
- jclass stringClass;
- jobjectArray strArray;
- jstring classNameStr;
- jstring startSystemServerStr;
-
- stringClass = env->FindClass("java/lang/String");
- assert(stringClass != NULL);
-
- strArray = env->NewObjectArray(2, stringClass, NULL);
- assert(strArray != NULL);
-
- classNameStr = env->NewStringUTF(className);
- assert(classNameStr != NULL);
-
- env->SetObjectArrayElement(strArray, 0, classNameStr);
-
- startSystemServerStr = env->NewStringUTF(startSystemServer ? "true" : "false");
-
- env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
-
-
-
-
-
- jclass startClass;
- jmethodID startMeth;
-
- slashClassName = strdup(className);
-
- for (cp = slashClassName; *cp != '\0'; cp++)
- if (*cp == '.')
- *cp = '/';
-
- startClass = env->FindClass(slashClassName);
- if (startClass == NULL) {
- LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
-
- } else {
-
- startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
- if (startMeth == NULL) {
- LOGE("JavaVM unable to find main() in '%s'\n", className);
-
- } else {
-
-
-
-
-
- env->CallStaticVoidMethod(startClass, startMeth, strArray);
-
- #if 0
- if (env->ExceptionCheck())
- threadExitUncaughtException(env);
- #endif
- }
- }
- LOGD("Shutting down VM\n");
- if (mJavaVM->DetachCurrentThread() != JNI_OK)
- LOGW("Warning: unable to detach main thread\n");
- if (mJavaVM->DestroyJavaVM() != 0)
- LOGW("Warning: VM did not shut down cleanly\n");
- bail:
- free(slashClassName);
- }
这个函数的作用是启动Android系统运行时库,它主要做了三件事情:
一是调用函数startVM启动虚拟机;
二是调用函数startReg注册JNI方法;
三是调用了com.android.internal.os.ZygoteInit类的main函数;
4.AndroidRuntime.cpp 启动虚拟机
- 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 heapsizeOptsBuf[sizeof("-Xmx")-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,
- #if defined(WITH_JIT)
- kEMJitCompiler,
- #endif
- } executionMode = kEMDefault;
-
-
- 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;
- #if defined(WITH_JIT)
- } else if (strcmp(propBuf, "int:jit") == 0) {
- executionMode = kEMJitCompiler;
- #endif
- }
-
- property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");
-
- property_get("dalvik.vm.check-dex-sum", propBuf, "");
- if (strcmp(propBuf, "true") == 0) {
- checkDexSum = true;
- }
-
- property_get("log.redirect-stdio", propBuf, "");
- if (strcmp(propBuf, "true") == 0) {
- logStdio = true;
- }
-
- strcpy(enableAssertBuf, "-ea:");
- property_get("dalvik.vm.enableassertions", enableAssertBuf+4, "");
-
- strcpy(jniOptsBuf, "-Xjniopts:");
- property_get("dalvik.vm.jniopts", jniOptsBuf+10, "");
-
-
- opt.extraInfo = (void*) runtime_exit;
- opt.optionString = "exit";
- mOptions.add(opt);
-
-
- opt.extraInfo = (void*) runtime_vfprintf;
- opt.optionString = "vfprintf";
- mOptions.add(opt);
-
- opt.extraInfo = NULL;
-
-
-
- opt.optionString = "-verbose:gc";
- mOptions.add(opt);
-
-
- strcpy(heapsizeOptsBuf, "-Xmx");
- property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
-
- opt.optionString = heapsizeOptsBuf;
- mOptions.add(opt);
-
-
-
-
-
- property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");
- if (dexoptFlagsBuf[0] != '\0') {
- const char* opc;
- const char* val;
-
- opc = strstr(dexoptFlagsBuf, "v=");
- if (opc != NULL) {
- switch (*(opc+2)) {
- case 'n': val = "-Xverify:none"; break;
- case 'r': val = "-Xverify:remote"; break;
- case 'a': val = "-Xverify:all"; break;
- default: val = NULL; break;
- }
-
- if (val != NULL) {
- opt.optionString = val;
- mOptions.add(opt);
- }
- }
-
- opc = strstr(dexoptFlagsBuf, "o=");
- if (opc != NULL) {
- switch (*(opc+2)) {
- case 'n': val = "-Xdexopt:none"; break;
- case 'v': val = "-Xdexopt:verified"; break;
- case 'a': val = "-Xdexopt:all"; break;
- default: val = NULL; break;
- }
-
- if (val != NULL) {
- opt.optionString = val;
- mOptions.add(opt);
- }
- }
-
- opc = strstr(dexoptFlagsBuf, "m=y");
- if (opc != NULL) {
- opt.optionString = "-Xgenregmap";
- mOptions.add(opt);
-
-
- opt.optionString = "-Xgc:precise";
- mOptions.add(opt);
- }
- }
-
-
- #ifdef HAVE_ANDROID_OS
-
- opt.optionString ="-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
- #else
-
- LOGI("Using TCP socket for JDWP\n");
- opt.optionString ="-agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=0";
- #endif
- mOptions.add(opt);
-
- char enableDPBuf[sizeof("-Xdeadlockpredict:") + PROPERTY_VALUE_MAX];
- property_get("dalvik.vm.deadlock-predict", propBuf, "");
- if (strlen(propBuf) > 0) {
- strcpy(enableDPBuf, "-Xdeadlockpredict:");
- strcat(enableDPBuf, propBuf);
- opt.optionString = enableDPBuf;
- mOptions.add(opt);
- }
-
- LOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
- if (checkJni) {
-
- opt.optionString = "-Xcheck:jni";
- mOptions.add(opt);
-
-
- opt.optionString = "-Xjnigreflimit:2000";
- mOptions.add(opt);
-
-
-
-
- }
-
- char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
- property_get("dalvik.vm.lockprof.threshold", propBuf, "");
- if (strlen(propBuf) > 0) {
- strcpy(lockProfThresholdBuf, "-Xlockprofthreshold:");
- strcat(lockProfThresholdBuf, propBuf);
- opt.optionString = lockProfThresholdBuf;
- mOptions.add(opt);
- }
-
- #if defined(WITH_JIT)
-
- char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];
- property_get("dalvik.vm.jit.op", propBuf, "");
- if (strlen(propBuf) > 0) {
- strcpy(jitOpBuf, "-Xjitop:");
- strcat(jitOpBuf, propBuf);
- opt.optionString = jitOpBuf;
- mOptions.add(opt);
- }
-
-
- char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];
- property_get("dalvik.vm.jit.method", propBuf, "");
- if (strlen(propBuf) > 0) {
- strcpy(jitMethodBuf, "-Xjitmethod:");
- strcat(jitMethodBuf, propBuf);
- opt.optionString = jitMethodBuf;
- mOptions.add(opt);
- }
- #endif
-
- if (executionMode == kEMIntPortable) {
- opt.optionString = "-Xint:portable";
- mOptions.add(opt);
- } else if (executionMode == kEMIntFast) {
- opt.optionString = "-Xint:fast";
- mOptions.add(opt);
- #if defined(WITH_JIT)
- } else if (executionMode == kEMJitCompiler) {
- opt.optionString = "-Xint:jit";
- mOptions.add(opt);
- #endif
- }
-
- if (checkDexSum) {
-
- opt.optionString = "-Xcheckdexsum";
- mOptions.add(opt);
- }
-
- if (logStdio) {
-
- opt.optionString = "-Xlog-stdio";
- mOptions.add(opt);
- }
-
- if (enableAssertBuf[4] != '\0') {
-
- if (strcmp(enableAssertBuf+4, "all") == 0)
- enableAssertBuf[3] = '\0';
- LOGI("Assertions enabled: '%s'\n", enableAssertBuf);
- opt.optionString = enableAssertBuf;
- mOptions.add(opt);
- } else {
- LOGV("Assertions disabled\n");
- }
-
- if (jniOptsBuf[10] != '\0') {
- LOGI("JNI options: '%s'\n", jniOptsBuf);
- opt.optionString = jniOptsBuf;
- mOptions.add(opt);
- }
-
- if (stackTraceFileBuf[0] != '\0') {
- static const char* stfOptName = "-Xstacktracefile:";
-
- stackTraceFile = (char*) malloc(strlen(stfOptName) +
- strlen(stackTraceFileBuf) +1);
- strcpy(stackTraceFile, stfOptName);
- strcat(stackTraceFile, stackTraceFileBuf);
- opt.optionString = stackTraceFile;
- mOptions.add(opt);
- }
-
-
- property_get("dalvik.vm.extra-opts", extraOptsBuf, "");
- parseExtraOpts(extraOptsBuf);
-
-
- {
- char langOption[sizeof("-Duser.language=") + 3];
- char regionOption[sizeof("-Duser.region=") + 3];
- strcpy(langOption, "-Duser.language=");
- strcpy(regionOption, "-Duser.region=");
- readLocale(langOption, regionOption);
- opt.extraInfo = NULL;
- opt.optionString = langOption;
- mOptions.add(opt);
- opt.optionString = regionOption;
- mOptions.add(opt);
- }
-
-
-
-
-
- opt.optionString = "-Djava.io.tmpdir=/sdcard";
- mOptions.add(opt);
-
- initArgs.version = JNI_VERSION_1_4;
- initArgs.options = mOptions.editArray();
- initArgs.nOptions = mOptions.size();
- initArgs.ignoreUnrecognized = JNI_FALSE;
-
-
-
-
-
-
-
-
-
- if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
- LOGE("JNI_CreateJavaVM failed\n");
- goto bail;
- }
-
- result = 0;
-
- bail:
- free(stackTraceFile);
- return result;
- }
5.AndroidRuntime.cpp 注册JNI函数
第4步中已经创建好了虚拟机,因此需要给该虚拟机注册一些JNI函数。
- int AndroidRuntime::startReg(JNIEnv* env)
- {
-
-
-
-
-
- androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
-
- LOGV("--- 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;
- }
-
- 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
- LOGD("----------!!! %s failed to load\n", array[i].mName);
- #endif
- return -1;
- }
- }
- return 0;
- }
- //gRegJNI全局数组中
- 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_pim_EventRecurrence),
- 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_security_Md5MessageDigest),
- REG_JNI(register_android_text_AndroidCharacter),
- REG_JNI(register_android_text_AndroidBidi),
- REG_JNI(register_android_text_KeyCharacterMap),
- REG_JNI(register_android_os_Process),
- REG_JNI(register_android_os_Binder),
- REG_JNI(register_android_view_Display),
- REG_JNI(register_android_nio_utils),
- REG_JNI(register_android_graphics_PixelFormat),
- REG_JNI(register_android_graphics_Graphics),
- REG_JNI(register_android_view_Surface),
- REG_JNI(register_android_view_ViewRoot),
- REG_JNI(register_com_google_android_gles_jni_EGLImpl),
- REG_JNI(register_com_google_android_gles_jni_GLImpl),
- 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_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_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_Typeface),
- REG_JNI(register_android_graphics_Xfermode),
- REG_JNI(register_android_graphics_YuvImage),
- REG_JNI(register_com_android_internal_graphics_NativeUtils),
-
- REG_JNI(register_android_database_CursorWindow),
- REG_JNI(register_android_database_SQLiteCompiledSql),
- REG_JNI(register_android_database_SQLiteDatabase),
- REG_JNI(register_android_database_SQLiteDebug),
- REG_JNI(register_android_database_SQLiteProgram),
- REG_JNI(register_android_database_SQLiteQuery),
- REG_JNI(register_android_database_SQLiteStatement),
- REG_JNI(register_android_os_Debug),
- REG_JNI(register_android_os_FileObserver),
- REG_JNI(register_android_os_FileUtils),
- REG_JNI(register_android_os_MessageQueue),
- REG_JNI(register_android_os_ParcelFileDescriptor),
- REG_JNI(register_android_os_Power),
- REG_JNI(register_android_os_StatFs),
- REG_JNI(register_android_os_SystemProperties),
- 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_WifiManager),
- REG_JNI(register_android_nfc_NdefMessage),
- REG_JNI(register_android_nfc_NdefRecord),
- 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_SensorManager),
- 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_ToneGenerator),
-
- REG_JNI(register_android_opengl_classes),
- REG_JNI(register_android_bluetooth_HeadsetBase),
- REG_JNI(register_android_bluetooth_BluetoothAudioGateway),
- REG_JNI(register_android_bluetooth_BluetoothSocket),
- REG_JNI(register_android_bluetooth_ScoSocket),
- REG_JNI(register_android_server_BluetoothService),
- REG_JNI(register_android_server_BluetoothEventLoop),
- REG_JNI(register_android_server_BluetoothA2dpService),
- REG_JNI(register_android_server_Watchdog),
- REG_JNI(register_android_message_digest_sha1),
- 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_hardware_fm_fmradio),
- REG_JNI(register_android_app_NativeActivity),
- REG_JNI(register_android_view_InputChannel),
- REG_JNI(register_android_view_InputQueue),
- REG_JNI(register_android_view_KeyEvent),
- REG_JNI(register_android_view_MotionEvent),
-
- REG_JNI(register_android_content_res_ObbScanner),
- REG_JNI(register_android_content_res_Configuration),
- };
6.ZygoteInit.java 调用了com.android.internal.os.ZygoteInit类的main函数
- public static void main(String argv[]) {
-
- try {
-
- VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
-
-
- SamplingProfilerIntegration.start();
-
- registerZygoteSocket();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
-
- preloadClasses();
- preloadResources();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());
-
-
- SamplingProfilerIntegration.writeZygoteSnapshot();
-
-
- gc();
-
-
- if (argv.length != 2) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
-
- if (argv[1].equals("true")) {
-
- startSystemServer();
- } else if (!argv[1].equals("false")) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
-
- Log.i(TAG, "Accepting command socket connections");
-
- if (ZYGOTE_FORK_MODE) {
- runForkMode();
- } else {
- runSelectLoopMode();
- }
- closeServerSocket();
- } catch (MethodAndArgsCaller caller) {
-
- caller.run();
- } catch (RuntimeException ex) {
- Log.e(TAG, "Zygote died with exception", ex);
- closeServerSocket();
- throw ex;
- }
- }
该main函数的作用:
<1>.调用registerZygoteSocket函数创建了一个socket接口,建立IPC通信的服务端;
<2> preloadClasses,preloadResources函数预加载类和资源
<2>.调用startSystemServer函数来启动SystemServer组件;
<3>.调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。
7.ZygoteInit.java 建立socket通信服务端
zygote 并没有采用binder通信机制,而是采用基于AF_UNIX类型的socket通信方式
- 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);
- }
- }
- }
8.ZygoteInit.java 预加载类和资源
- private static void preloadClasses() {
- final VMRuntime runtime = VMRuntime.getRuntime();
-
- InputStream is = ZygoteInit.class.getClassLoader().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);
- setEffectiveUser(UNPRIVILEGED_UID);
-
-
-
- float defaultUtilization = runtime.getTargetHeapUtilization();
- runtime.setTargetHeapUtilization(0.8f);
-
-
- runtime.gcSoftReferences();
- runtime.runFinalizationSync();
- Debug.startAllocCounting();
-
- try {
- BufferedReader br= new BufferedReader(new InputStreamReader(is), 256);
-
- int count = 0;
- String line;
-
- while ((line = br.readLine()) != null) {
-
- line = line.trim();
- if (line.startsWith("#") || line.equals("")) {
- continue;
- }
-
- try {
- if (Config.LOGV) {
- Log.v(TAG, "Preloading " + line + "...");
- }
-
- Class.forName(line);
- if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
- if (Config.LOGV) {
- Log.v(TAG," GC at " + Debug.getGlobalAllocSize());
- }
- runtime.gcSoftReferences();
- runtime.runFinalizationSync();
- Debug.resetGlobalAllocSize();
- }
- count++;
- } catch (ClassNotFoundException e) {
- Log.w(TAG, "Class not found for preloading: " + line);
- } catch (Throwable t) {
- Log.e(TAG, "Error preloading " + line + ".", t);
- if (t instanceof Error) {
- throw (Error) t;
- }
- if (t instanceof RuntimeException) {
- throw (RuntimeException) t;
- }
- throw new RuntimeException(t);
- }
- }
-
- Log.i(TAG, "...preloaded " + count + " classes in "
- + (SystemClock.uptimeMillis()-startTime) + "ms.");
- } catch (IOException e) {
- Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
- } finally {
-
- runtime.setTargetHeapUtilization(defaultUtilization);
-
- Debug.stopAllocCounting();
-
-
- setEffectiveUser(ROOT_UID);
- setEffectiveGroup(ROOT_GID);
- }
- }
- }
preloadClasses 执行时间比较长,也是导致android系统启动慢的原因。
加载共享资源
- private static void preloadResources() {
- final VMRuntime runtime = VMRuntime.getRuntime();
-
- Debug.startAllocCounting();
- try {
- runtime.gcSoftReferences();
- 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);
- 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);
- 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();
- }
- }
9.ZygoteInit.java 启动SystemServer
- private static boolean startSystemServer()
- throws MethodAndArgsCaller, RuntimeException {
-
- String args[] = {
- "--setuid=1000",
- "--setgid=1000",
- "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
- "--capabilities=130104352,130104352",
- "--runtime-init",
- "--nice-name=system_server",
- "com.android.server.SystemServer",
- };
- ZygoteConnection.Arguments parsedArgs = null;
-
- int pid;
-
- try {
- parsedArgs = new ZygoteConnection.Arguments(args);
-
-
-
-
-
- int debugFlags = parsedArgs.debugFlags;
- if ("1".equals(SystemProperties.get("ro.debuggable")))
- debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
-
-
- pid = Zygote.forkSystemServer(
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, debugFlags, null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities);
- } catch (IllegalArgumentException ex) {
- throw new RuntimeException(ex);
- }
-
-
- if (pid == 0) {
-
- handleSystemServerProcess(parsedArgs);
- }
-
- return true;
- }
Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。
10.ZygoteInit.java 循环等待客户端的连接
- private static void runSelectLoopMode() throws MethodAndArgsCaller {
- ArrayList<FileDescriptor> fds = new ArrayList();
- ArrayList<ZygoteConnection> peers = new ArrayList();
- 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);
- fds.add(newPeer.getFileDesciptor());
- } else {
- boolean done;
-
- done = peers.get(index).runOnce();
-
- if (done) {
- peers.remove(index);
- fds.remove(index);
- }
- }
- }
- }
zygote总结:
1.创建AppRuntime对象,并调用它的start函数;
2.调用startVm创建Java虚拟机;
3.调用startReg函数来注册JNI函数;
4.调用ZygoteInit类的main函数,从此就进入了Java世界;
5.调用registerZygoteSocket 注册一个服务端socket;
6.调用preloadClasses 函数加载类资源;
7.调用preloadResources函数加载系统资源;
8.调用startSystemServer函数创建SystemServer进程;
9.调用runSelectLoopMode函数进入服务端socket监听;