Zygote是init启动的第一个进程。
所有的system server 都是从Zygote fork来的。
// 进程名称是zygote,运行的二进制文件在/system/bin/app_process64 // 启动参数是 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main priority -20 user root group root readproc socket zygote stream 660 root system //创建一个socket,名字叫zygote,以tcp形式 onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd onrestart restart wificond writepid /dev/cpuset/foreground/tasks //创建子进程时,向/dev/cpuset/foreground/tasks 写入pid // 另一个service ,名字 zygote_secondary service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload class main priority -20 user root group root readproc socket zygote_secondary stream 660 root system onrestart restart zygote writepid /dev/cpuset/foreground/tasks
定义在 platform/system/core/rootdir/init.rc
# It is recommended to put unnecessary data/ initialization from post-fs-data # to start-zygote in device s init.rc to unblock zygote start. on zygote-start && property:ro.crypto.state=unencrypted # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary on zygote-start && property:ro.crypto.state=unsupported # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary
zygote在哪里触发
on late-init ... trigger zygote-start
late-init 在哪里启动
在init进程进入循环的最后一个地方
if (bootmode == "charger") { am.QueueEventTrigger("charger"); } else { am.QueueEventTrigger("late-init"); }
这个就是init进程启动Zygote的由来。
为什么要有Zygote,虽然init是android系统启动的第一个进程,但是init来管理的事情太多了,如果都是有init来触发启动其他android进程,这个init事情就太多了。所以通过Zygote来启动其他进程,就把android其他进程由Zygote来负责了。
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
在app_main.cpp种定义了Zygote的解析过程。
int main(int argc, char* const argv[]) { //将参数argv放到argv_String字符串中,然后打印出来 //之前start zygote传入的参数是 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote if (!LOG_NDEBUG) { String8 argv_String; for (int i = 0; i < argc; ++i) { argv_String.append("/""); argv_String.append(argv[i]); argv_String.append("/" "); } ALOGV("app_process main with argv: %s", argv_String.string()); } AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));//构建AppRuntime对象,并将参数传入 // Process command line arguments // ignore argv[0] argc--; argv++; // Everything up to -- or first non - arg goes to the vm. // // The first argument after the VM args is the "parent dir", which // is currently unused. // // After the parent dir, we expect one or more the following internal // arguments : // // --zygote : Start in zygote mode // --start-system-server : Start the system server. // --application : Start in application (stand alone, non zygote) mode. // --nice-name : The nice name for this process. // // For non zygote starts, these arguments will be followed by // the main class name. All remaining arguments are passed to // the main method of this class. // // For zygote starts, all remaining arguments are passed to the zygote. // main function. // // Note that we must copy argument string values since we will rewrite the // entire argument block when we apply the nice name to argv0. // // As an exception to the above rule, anything in "spaced commands" // goes to the vm even though it has a space in it. //上面这段英文大概讲的是,所有在 "--" 后面的非 "-"开头的参数都将传入vm, 但是有个例外是spaced commands数组中的参数 const char* spaced_commands[] = { "-cp", "-classpath" };//这两个参数是Java程序需要依赖的Jar包,相当于import // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s). bool known_command = false; int i; for (i = 0; i < argc; i++) { if (known_command == true) { //将spaced_commands中的参数额外加入VM runtime.addOption(strdup(argv[i])); ALOGV("app_process main add known option %s ", argv[i]); known_command = false; continue; } for (int j = 0; j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0])); ++j) { if (strcmp(argv[i], spaced_commands[j]) == 0) {//比较参数是否是spaced_commands中的参数 known_command = true; ALOGV("app_process main found known command %s ", argv[i]); } } if (argv[i][0] != - ) { //如果参数第一个字符是 - ,直接跳出循环,之前传入的第一个参数是 -Xzygote,所以执行到这儿就跳出了,i=0 break; } if (argv[i][1] == - && argv[i][2] == 0) { ++i; // Skip --. break; } runtime.addOption(strdup(argv[i])); ALOGV("app_process main add option %s ", argv[i]); } // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; // Skip unused "parent dir" argument. //跳过一个参数,之前跳过了-Xzygote,这里继续跳过 /system/bin ,也就是所谓的 "parent dir" while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) {//表示是zygote启动模式 zygote = true; niceName = ZYGOTE_NICE_NAME;//这个值根据平台可能是zygote64或zygote } else if (strcmp(arg, "--start-system-server") == 0) {//需要启动SystemServer startSystemServer = true; } else if (strcmp(arg, "--application") == 0) {//表示是application启动模式,也就是普通应用程序 application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) {//进程别名 niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) {//application启动的class className.setTo(arg); break; } else { --i; break; } } Vector<String8> args; if (!className.isEmpty()) {//className不为空,说明是application启动模式 // We re not in zygote mode, the only argument we need to pass // to RuntimeInit is the application argument. // // The Remainder of args get passed to startup class main(). Make // copies of them before we overwrite them with the process name. args.add(application ? String8("application") : String8("tool")); runtime.setClassNameAndArgs(className, argc - i, argv + i);//将className和参数设置给runtime if (!LOG_NDEBUG) {//打印class带的参数 String8 restOfArgs; char* const* argv_new = argv + i; int argc_new = argc - i; for (int k = 0; k < argc_new; ++k) { restOfArgs.append("/""); restOfArgs.append(argv_new[k]); restOfArgs.append("/" "); } ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string()); } } else { //zygote启动模式 // We re in zygote mode. maybeCreateDalvikCache(); //新建Dalvik的缓存目录 if (startSystemServer) {//加入start-system-server参数 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); //加入--abi-list=参数 // In zygote mode, pass all remaining arguments to the zygote // main() method. for (; i < argc; ++i) {//将剩下的参数加入args args.add(String8(argv[i])); } } if (!niceName.isEmpty()) {//设置进程别名 runtime.setArgv0(niceName.string(), true /* setProcName */); } if (zygote) { //如果是zygote启动模式,则加载ZygoteInit runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) {//如果是application启动模式,则加载RuntimeInit 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."); } }
参数描述:
// --zygote : Start in zygote mode
// --start-system-server : Start the system server.
// --application : Start in application (stand alone, non zygote) mode.
这段描述以及解释清楚。
整个过程其实是2个部分
AppRuntime,虚拟机的启动,是在这个类里面执行的。
如上面的注解,如果传入的是start-system-server就
startSystemServer = true;
然后在后面的位置
if (startSystemServer) {//加入start-system-server参数 args.add(String8("start-system-server")); } runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
zygote启动模式,也就是start-system-server模式,就启动com.android.internal.os.ZygoteInit进程的虚拟机。
因为android是一个进程,一个虚拟机进程。
如果是启动application,就会走到
application = true;
后面就启动
} else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
这里就是通过jvm启动一个application的进程
platform/frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { ... //打印一些日志,获取ANDROID_ROOT环境变量 /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL);//初始化JNI,加载libart.so JNIEnv* env; if (startVm(&mJavaVM, &env, zygote) != 0) {//创建虚拟机 return; } onVmCreated(env);//表示虚拟创建完成,但是里面是空实现 /* * Register android functions. */ if (startReg(env) < 0) {注册JNI函数 ALOGE("Unable to register all android natives/n"); return; } ... //JNI方式调用ZygoteInit类的main函数 }
startVm启动虚拟机
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { ... //打印一些日志,获取ANDROID_ROOT环境变量 /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL);//初始化JNI,加载libart.so JNIEnv* env; if (startVm(&mJavaVM, &env, zygote) != 0) {//创建虚拟机 return; } onVmCreated(env);//表示虚拟创建完成,但是里面是空实现 /* * Register android functions. */ if (startReg(env) < 0) {注册JNI函数 ALOGE("Unable to register all android natives/n"); return; } ... //JNI方式调用ZygoteInit类的main函数 }
/* * 1.FindSymbol函数内部实际调用的是dlsym * 2.dlsym作用是根据 动态链接库 操作句柄(handle)与符号(symbol),返回符号对应的地址 * 3.这里实际就是从libart.so中将JNI_GetDefaultJavaVMInitArgs等对应的地址存入&JNI_GetDefaultJavaVMInitArgs_中 */ if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_), "JNI_GetDefaultJavaVMInitArgs")) { return false; } if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_), "JNI_CreateJavaVM")) { return false; } if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_), "JNI_GetCreatedJavaVMs")) { return false; } return true;
Init函数主要作用是初始化JNI,具体工作是首先通过dlopen加载libart.so获得其句柄,然后调用dlsym从libart.so中找到
JNI_GetDefaultJavaVMInitArgs、JNI_CreateJavaVM、JNI_GetCreatedJavaVMs三个函数地址,赋值给对应成员属性,
这三个函数会在后续虚拟机创建中调用.
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) { JavaVMInitArgs initArgs; ... addOption("exit", (void*) runtime_exit);各//将参数放入mOptions数组中 ... initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray();//将mOptions赋值给initArgs initArgs.nOptions = mOptions.size(); initArgs.ignoreUnrecognized = JNI_FALSE; if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {//调用libart.so的JNI_CreateJavaVM函数 ALOGE("JNI_CreateJavaVM failed/n"); return -1; } return 0; } extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args); } jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { return JNI_CreateJavaVM_(p_vm, p_env, vm_args);//调用之前初始化的JNI_CreateJavaVM_ }
主要就是存储一些参数到mOptions 里面,另外就是调用JNI_CreateJavaVM方法调起VM
startReg首先是设置了Android创建线程的处理函数,然后创建了一个200容量的局部引用作用域,用于确保不会出现OutOfMemoryException, 最后就是调用register_jni_procs进行JNI注册
我们看看register_jni_procs传入的RegJNIRec数组gRegJNI,里面就是一堆的函数指针
static const RegJNIRec gRegJNI[] = { REG_JNI(register_com_android_internal_os_RuntimeInit), REG_JNI(register_com_android_internal_os_ZygoteInit), REG_JNI(register_android_os_SystemClock), REG_JNI(register_android_util_EventLog), REG_JNI(register_android_util_Log), REG_JNI(register_android_util_MemoryIntArray) ... }
我们随便看一个register_com_android_internal_os_ZygoteInit,这实际上是自定义JNI函数并进行动态注册的标准写法,
内部是调用JNI的RegisterNatives,这样注册后,Java类ZygoteInit的native方法nativeZygoteInit就会调用com_android_internal_os_ZygoteInit_nativeZygoteInit函数
int register_com_android_internal_os_ZygoteInit(JNIEnv* env) { const JNINativeMethod methods[] = { { "nativeZygoteInit", "()V", (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit }, }; return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit", methods, NELEM(methods)); }
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { /* * 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. */ //接下来的这些语法大家应该比较熟悉了,都是JNI里的语法,主要作用就是调用ZygoteInit类的main函数 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); 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);//找到class if (startClass == NULL) { ALOGE("JavaVM unable to locate class %s /n", slashClassName); /* keep going */ } else { 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 { env->CallStaticVoidMethod(startClass, startMeth, strArray);//调用main函数 #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"); }