这篇文章主要介绍了详细分析Android中实现Zygote的源码,包括底层的C/C++代码以及Java代码部分入口,需要的朋友可以参考下
概述
在Android系统中,所有的应用程序进程,以及用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。zygote进程是通过复制自身的方式来创建System进程和应用程序进程的。由于zygote进程在启动时会在内部创建一个虚拟机实例,因此,通过复制zygote进程而得到的System进程和应用程序进程可以快速地在内部获得一个虚拟机实例拷贝。
zygote进程在启动完成之后,会马上将System进程启动起来,以便它可以将系统的关键服务启动起来。下面我们将介绍zygote进程的启动脚本,然后分析它和System进程的启动过程。
zygote分析
zygote进程的启动脚本如下:
- 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
 
解析配置文件
在我之前的一篇博客中已经分析了init进程是如何启动service服务了,需要了解的同学可以参考这篇文章:Android init进程——
通过zygote服务的启动脚本,我们可以知道,zygote进程的实际是二进制文件app_process的调用,我们就从这个应用程序的main函数入手去分析一下zygote进程的启动过程,源码如下(/frameworks/base/cmds/app_process/app_main.cpp):
- /**
 - * 将-Xzygote加入到JavaVMOption中,返回/system/bin参数指向的下标
 - */
 - 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) {
 - // 进入到AppRuntime的start函数
 - 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函数中,通过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):
- 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文件中关于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:
- 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".
 - *
 - * 这两个参数的值分别为:
 - * 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)));
 - }
 - // 设置ANDROID_ROOT环境变量
 - 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. 创建虚拟机
 - if (startVm(&mJavaVM, &env) != 0) {
 - return;
 - }
 - onVmCreated(env);
 - // 2. 注册JNI函数
 - 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);
 - // 创建一个有两个元素的String数组,用Java代码表示为:String[] strArray = new String[2];
 - strArray = env->NewObjectArray(2, stringClass, NULL);
 - assert(strArray != NULL);
 - classNameStr = env->NewStringUTF(className);
 - assert(classNameStr != NULL);
 - // 设置第一个元素为"com.android.internal.os.ZygoteInit"
 - env->SetObjectArrayElement(strArray, 0, classNameStr);
 - optionsStr = env->NewStringUTF(options);
 - // 设置第二个元素为"start-system-server"
 - env->SetObjectArrayElement(strArray, 1, optionsStr);
 - // 将字符串"com.android.internal.os.ZygoteInit"转换为"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.
 - // 通过JNI调用java函数,注意调用的是main函数,所属的类是"com.android.internal.os.ZygoteInit".
 - // 传递的参数是"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");
 - }
 - }
 
上述代码有几处关键点,分别是:
创建虚拟机。
注册JNI函数。
进入Java世界。
接下来,我们分别分析这三个关键点。
创建虚拟机——startVm
startVm并没有特别之处,就是调用JNI的虚拟机创建函数,但是创建虚拟机时的一些参数却是在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;
 - /**
 - * 这段代码是用了设置JNI_check选项的。JNI_check指的是Native层调用JNI函数时,系统所做的一些检查动作。
 - * 这个选项虽然能增加可靠性,但是还有一些副作用:
 - * 1. 因为检查工作比较耗时,所以会影响系统运行速度。
 - * 2. 有些检查工作比较耗时,一旦出错,整个进程会abort。
 - * 所以,JNI_check选项一般只在eng版本设置。
 - */
 - 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;
 - }
 - // ... 省略大部分参数设置
 - /**
 - * 设置虚拟机的heapsize,默认为16m。绝大多数厂商都会在build.prop文件里修改这个属性,一般是256m。
 - * heapsize不能设置得过小,否则在操作大尺寸的图片时无法分配所需的内存。
 - */
 - 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;
 - }
 
更多虚拟机参数的设置,我这里就不做特殊说明了,大家感兴趣可以自行google。(ps:因为我不太懂虚拟机这一块…)
注册JNI函数——startReg
上面讲了如何创建虚拟机,接下来需要给这个虚拟机注册一些JNI函数。正是因为后续的Java世界用到的一些函数是采用native方式实现的,所以才必须提前注册这些函数。
接下来,我们来看一下startReg函数的源码实现:
- int AndroidRuntime::startReg(JNIEnv* env)
 - {
 - // 设置Thread类的线程创建函数为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;
 - }
 
关键是需要注册JNI函数,具体实现是由register_jni_procs函数实现的,我们来看一下这个函数的具体实现(/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;
 - }
 
通过源码,我们可以看到,register_jni_procs只是对array数组的mProc函数的封装,而array数组指向的是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_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是一个宏,宏里面包括的就是那个参数为JNIEnv*,返回值为int的函数指针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其实就是为Java类注册JNI函数。
进入JAVA世界
可以看到CallStaticVoidMethod最终将调用com.android.internal.os.ZygoteInit的main函数,下面就来看一下这个Java世界的入口函数。源码位置:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,源码如下:
- public static void main(String argv[])
 - {
 - try {
 - SamplingProfilerIntegration.start();
 - // 1. 注册zygote用的socket
 - registerZygoteSocket();
 - EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
 - // 2. 预加载类和资源
 - preload();
 - EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());
 - SamplingProfilerIntegration.writeZygoteSnapshot();
 - // 强制执行一次垃圾收集
 - gc();
 - Trace.setTracingEnabled(false);
 - if (argv.length != 2) {
 - throw new RuntimeException(argv[0] + USAGE_STRING);
 - }
 - if (argv[1].equals("start-system-server")) {
 - // 3. 启动system-server
 - startSystemServer();
 - } else if (!argv[1].equals("")) {
 - throw new RuntimeException(argv[0] + USAGE_STRING);
 - }
 - Log.i(TAG, "Accepting command socket connections");
 - // 4. 进入请求应答模式
 - runSelectLoop();
 - closeServerSocket();
 - } catch(MethodAndArgsCaller caller) {
 - caller.run();
 - } catch(RuntimeException ex) {
 - Log.e(TAG, "Zygote died with exception", ex);
 - closeServerSocket();
 - throw ex;
 - }
 - }
 
上述代码中有5个重要的点,我已经通过标号标记出来了,接下来我们分别分析一下这5点函数的具体实现。
建立IPC通信服务端——registerZygoteSocket
zygote及系统中其他程序的通信没有使用Binder,而是采用了基于AF_UNIX类型的socket。registerZygoteSocket函数的使命正是建立这个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);
 - }
 - }
 - }
 - 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);
 - localAddress = impl.getSockAddress();
 - }
 - }
 
registerZygoteSocket很简单,就是创建一个服务端的socket。
预加载类和资源——preload
我们先来看一下preload函数实现:
- static void preload()
 - {
 - preloadClasses();
 - preloadResources();
 - preloadOpenGL();
 - }
 
preload函数里面分别调用了三个预加载函数,我们分别来分析一下这几个函数的实现。
首先是preloadClasses,函数实现如下:
- 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 {
 - // 创建一个缓冲区为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看起来很简单,但是实际上它有很多的类需要加载。可以查看一下/frameworks/base/preloaded-classes文件,这里面都是需要预加载的类。
接下来,分析一下preloadResources函数的源码:
- 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();
 - }
 - }
 
接下来,是预加载OpenGL。源码如下:
- private static void preloadOpenGL()
 - {
 - if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) {
 - EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
 - }
 - }
 
启动system_server
现在我们要分析第三个关键点:startSystemServer。这个函数会创建java世界中系统Service所驻留的进程system_server,该进程是framework的核心。如何system_server挂掉,会导致zygote自杀。我们来看一下startSystemServer()实现源码。
- /**
 - * 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
 - );
 - // 设置参数
 - 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", // 进程名为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;
 - }
 
| 				 
  | 		
有求必应之等待请求——runSelectLoop
zygote从startSystemServer返回后,将进入第四个关键的函数:runSelectLoop。我们来看一下这个函数的实现:
- 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);
 - }
 - }
 - }
 
新闻热点
疑难解答