其实我们仔细想一想,就会觉得zygote的整个流程实际上是非常符合实际情况的。
✨✨ 在Android中,每个进程都运行在对应的虚拟机上,因此zygote首先就负责创建出虚拟机。
✨✨ 然后,为了反射调用java代码,必须有对应的JNI函数,于是zygote进行了JNI函数的注册。
✨✨ 当一切准备妥当后,zygote进程才进入到了java世界。
现在我们跟进ZygoteInit.java的main函数。
public static void main(String argv[]) { //创建ZygoteServer对象 ZygoteServer zygoteServer = new ZygoteServer(); // Mark zygote start. This ensures that thread creation will throw // an error. // 调用native函数,确保当前没有其它线程在运行 // 主要还是处于安全的考虑 ZygoteHooks.startZygoteNoThreadCreation(); // Zygote goes into its own process group. try { Os.setpgid(0, 0); } catch (ErrnoException ex) { throw new RuntimeException("Failed to setpgid(0,0)", ex); } final Runnable caller; try { ... ... RuntimeInit.enableDdms(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; boolean enableLazyPreload = false; // 解析参数,得到上述变量的值 for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; } else if ("--enable-lazy-preload".equals(argv[i])) { enableLazyPreload = 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."); } zygoteServer.registerServerSocket(socketName); // 注册server socket // In some configurations, we avoid preloading resources and classes eagerly. // In such cases, we will preload things prior to our first fork. if (!enableLazyPreload) { ... ... preload(bootTimingsTraceLog); // 默认情况,预加载信息 ... ... } else { // 如注释,延迟预加载 // 变更Zygote进程优先级为NORMAL级别 // 第一次fork时才会preload Zygote.resetNicePriority(); } // Do an initial gc to clean up after startup bootTimingsTraceLog.traceBegin("PostZygoteInitGC"); gcAndFinalize(); // 如果预加载了,很有必要GC一波 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC ... ... // Zygote process unmounts root storage spaces. Zygote.nativeUnmountStorageOnInit(); // Set seccomp policy // 加载seccomp的过滤规则 // 所有 Android 软件都使用系统调用(简称为 syscall)与 Linux 内核进行通信 // 内核提供许多特定于设备和SOC的系统调用,让用户空间进程(包括应用)可以直接与内核进行交互 // 不过,其中许多系统调用Android未予使用或未予正式支持 // 通过seccomp,Android可使应用软件无法访问未使用的内核系统调用 // 由于应用无法访问这些系统调用,因此,它们不会被潜在的有害应用利用 // 该过滤器安装到zygote进程中,由于所有Android应用均衍生自该进程 // 因而会影响到所有应用 Seccomp.setPolicy(); /// M: Added for BOOTPROF addBootEvent("Zygote:Preload End"); /// @} ZygoteHooks.stopZygoteNoThreadCreation(); // 允许有其它线程了 if (startSystemServer) { Runnable r = forkSystemServer(abiList, socketName, zygoteServer); // fork出system server // {@code r == null} in the parent (zygote) process, and {@code r != null} in the // child (system_server) process. if (r != null) { r.run(); return; } } Log.i(TAG, "Accepting command socket connections"); // The select loop returns early in the child process after a fork and // loops forever in the zygote. caller = zygoteServer.runSelectLoop(abiList); // zygote进程进入无限循环,处理请求 } catch (Throwable ex) { ... ... } finally { zygoteServer.closeServerSocket(); } // We're in the child process and have exited the select loop. Proceed to execute the // command. if (caller != null) { caller.run(); } }