上一篇中解析了init进程的启动流程,其中最后创建了zygote进程,本篇我们来详细分析zygote进程启动的部分。
Zygote进程又名孵化器进程,正如其名,它主要用于孵化子进程。所有的Java应用程序进程及系统服务SystemServer进程都由Zygote进程通过Linux的fork()函数孵化出来的,这也就是为什么把它称为Zygote的原因,因为他就像一个孵化器,孵化出无数子进程,而native程序则由Init程序创建启动。Zygote进程最初的名字不是“zygote”而是“app_process”,这个名字是在Android.mk文件中定义的,Zgyote是Android中的第一个art虚拟机,他通过socket的方式与其他进程进行通信。这里的“其他进程”其实主要是系统进程——SystemServer。
我们接着从上一篇app_main.cpp开始分析,源码如下(源码基于7.0):
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]) { if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return // EINVAL. Don't die on such kernels. if (errno != EINVAL) { LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno)); return 12; } } AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); // Process command line arguments // ignore argv[0] argc--; argv++; int i; for (i = 0; i < argc; i++) { if (argv[i][0] != '-') { break; } if (argv[i][1] == '-' && argv[i][2] == 0) { ++i; // Skip --. break; } runtime.addOption(strdup(argv[i])); } bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; // Skip unused "parent dir" argument. while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = ZYGOTE_NICE_NAME; } 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) == 0) { niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } Vector<String8> args; if (!className.isEmpty()) { args.add(application ? String8("application") : String8("tool")); runtime.setClassNameAndArgs(className, argc - i, argv + i); } else { // We're in zygote mode. maybeCreateDalvikCache(); if (startSystemServer) { // 1 args.add(String8("start-system-server")); } char prop[PROP_VALUE_MAX]; if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.", ABI_LIST_PROPERTY); return 11; } String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); // In zygote mode, pass all remaining arguments to the zygote // main() method. for (; i < argc; ++i) { args.add(String8(argv[i])); } } if (!niceName.isEmpty(app_main)) { runtime.setArgv0(niceName.string()); set_process_name(niceName.string()); } if (zygote) { // 2 runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } 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; } }上面注释1处将start-system-server作为参数放入到了args中,接着在注释2处调用了runtime.start(),也就是AppRuntime.cpp的start, 因为AppRuntime.cpp中没有此方法,AndroidRuntime.cpp是AppRuntime.cpp的父类,最终调用的是AndroidRuntime.cpp中的start方法来启动zygote。
frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { ALOGD(">>>>>> START %s uid %d <<<<<<\n", className != NULL ? className : "(unknown)", getuid()); static const String8 startSystemServer("start-system-server"); ... /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; //1 启动虚拟机 if (startVm(&mJavaVM, &env, zygote) != 0) { return; } onVmCreated(env); /* * Register android functions. */ //2 注册jni if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } /* * We want to call main() with a String array with arguments in it. * At present we have two arguments, the class name and an option string. * Create an array to hold them. */ jclass stringClass; jobjectArray strArray; jstring classNameStr; stringClass = env->FindClass("java/lang/String"); assert(stringClass != NULL); strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); assert(strArray != NULL); //className是com.android.internal.os.ZygoteInit classNameStr = env->NewStringUTF(className); assert(classNameStr != NULL); env->SetObjectArrayElement(strArray, 0, classNameStr); for (size_t i = 0; i < options.size(); ++i) { jstring optionsStr = env->NewStringUTF(options.itemAt(i).string()); assert(optionsStr != NULL); env->SetObjectArrayElement(strArray, i + 1, optionsStr); } /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { //3 找到ZygoteInit的main函数 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { //4 通过JNI调用ZygoteInit的main函数 env->CallStaticVoidMethod(startClass, startMeth, strArray); #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } } free(slashClassName); ALOGD("Shutting down VM\n"); if (mJavaVM->DetachCurrentThread() != JNI_OK) ALOGW("Warning: unable to detach main thread\n"); if (mJavaVM->DestroyJavaVM() != 0) ALOGW("Warning: VM did not shut down cleanly\n"); }上面注释1处startVm方法创建虚拟机,注释2处startRg来为DVM注册JNI, 注释3处的startClass是从app_main.cpp带过来的参数为com.android.internal.os.ZygoteInit,注释4处通过jni调用java层的ZygoteInit.java的main函数。
其中注释2处的注册JNI就是为了后面native和java层互相调用,其中部分源码如下:
frameworks/base/core/jni/android_util_Binder.cpp
int register_android_os_Binder(JNIEnv* env) { //1 if (int_register_android_os_Binder(env) < 0) return -1; if (int_register_android_os_BinderInternal(env) < 0) return -1; if (int_register_android_os_BinderProxy(env) < 0) return -1; jclass clazz = FindClassOrDie(env, "android/util/Log"); gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I"); clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor"); gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); clazz = FindClassOrDie(env, "android/os/StrictMode"); gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz, "onBinderStrictModePolicyChange", "(I)V"); return 0; }我们以注释1处的int_register_android_os_Binder为例,可以看到java和native一一对应的关系(其余两个BinderInternal和BinderProxy同理查看):
static const JNINativeMethod gBinderMethods[] = { /* name, signature, funcPtr */ { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid }, { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy }, { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands }, { "init", "()V", (void*)android_os_Binder_init }, { "destroy", "()V", (void*)android_os_Binder_destroy }, { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable } }; const char* const kBinderPathName = "android/os/Binder"; static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz = FindClassOrDie(env, kBinderPathName); // 方便java和native互相调用 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z"); gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); return RegisterMethodsOrDie( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); }frameworks/base/core/java/com/android/internal/os/ZygoteInit
public static void main(String argv[]) { // Mark zygote start. This ensures that thread creation will throw // an error. ZygoteHooks.startZygoteNoThreadCreation(); try { Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit"); RuntimeInit.enableDdms(); // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { //1 startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } if (abiList == null) { throw new RuntimeException("No ABI list supplied."); } /** * 2 注册zygote进程的socket */ registerZygoteSocket(socketName); Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload"); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); // 3 预加载类库和资源 preload(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); Trace.traceEnd(Trace.TRACE_TAG_DALVIK); ... // 4 此处为true, 启动systemServer进程 if (startSystemServer) { startSystemServer(abiList, socketName); } Log.i(TAG, "Accepting command socket connections"); //5 循环等待客户端的创建进程请求 runSelectLoop(abiList); closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (Throwable ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } }上面的流程如下:
注释1处start-system-server参数就是在上面app_main.cpp中传递的,所以这里为true注释2注册zygote进程的socket,便于systemserver进程的AMS(ActivityManagerService)和zygote进程通信,用来创建新的应用程序进程。注释3处preload方法会主要调用preloadClasses()和preloadResources()加载类和资源。注释4处启动systemserver进程。注释5处不断的while循环用来等待AMS发送创建应用程序进程的请求。registerZygoteSocket方法用来创建LocalServerSocket对象,针对与systemserver进程来说是服务端,等到zygote将systemserver进程启动结束后,就会在这里的socket上等待AMS发送的请求zygote进程创建新的应用程序进程的请求。
在注释1处的args参数中,看到systemserver进程的uid和gid都是1000,并且进程名字为system_server,类名为com.android.server.SystemServer,在注释2处通过Zygote.forkSystemServer来创建子进程,返回一个pid,在注释3处根据返回的pid来执行逻辑,如果pid==0, 说明逻辑运行在子进程中,接着执行注释4处的handleSystemServerProcess来启动system_server进程。
以上代码主要逻辑如下:
注释1处的sServerSocket是registerZygoteSocket中创建的,调用sServerSocket.getFileDescriptor()用来获得该Socket的fd字段的值并添加到fd列表fds中,接下来while无限循环等待AMS发送请求创建新的应用程序进程。注释2处将fds中存储的FileDescriptor转存到pollFds中。注释3处对pollFds进行遍历。注释4处i==0说明zygote进程和system_server进程的AMS建立了连接,通过acceptCommandPeer返回ZygoteConnection,然后将相关对象分别添加到peers和fds中。注释5处如果i>0的话,说明ActivityManagerService向Zygote进程发送了一个创建应用进程的请求,然后调用ZygoteConnection的runOnce函数来创建一个新的应用程序进程。并在成功创建后将这个连接从Socket连接列表peers和fd列表fds中清除。