前言

因为源码剖析的代码量比拟大,大部分博客网站的内容显示页面都比拟窄,显示进去的成果都异样俊俏,所以您也能够间接查看 《 Thinking in Android 》 来浏览这边文章(也能够点击 RSS 订阅查看代码更不便),心愿这篇文章能帮你梳理分明 “Zygote 过程的原理”


外围源码

要害类门路
init.rcsystem/core/rootdir/init.rc
init.cppsystem/core/init/init.cpp
init.zygote64.rcsystem/core/rootdir/init.zygote64.rc
builtins.cppsystem/core/init/builtins.cpp
service.cppsystem/core/init/service.cpp
app_main.cppframeworks/base/cmds/app_process/app_main.cpp
AndroidRuntime.cppframeworks/base/core/jni/AndroidRuntime.cpp
JniInvocation.cpplibnativehelper/JniInvocation.cpp
LocalServerSocket.cppframeworks/base/core/java/android/net/LocalServerSocket.java
ZygoteInit.javaframeworks/base/core/java/com/android/internal/os/ZygoteInit.java
ZygoteServer.javaframeworks/base/core/java/com/android/internal/os/ZygoteServer.java


Zygote 简介

在 Android 零碎中,JavaVM(Java 虚拟机)应用程序过程以及运行零碎要害服务的 SystemServer 过程都是由 Zygote 来创立的,咱们也将它称为 孵化器。它通过 fock (复制过程)的模式来创立 "应用程序过程""SystemServer 过程",因为 Zygote 过程在启动时会创立 JavaVM,因而通过 fock 而创立的 "应用程序过程" 和 "SystemServer 过程" 能够在外部获取一个 JavaVM 的实例拷贝


一、Zygote

1.1 触发

在后面剖析 init 过程 时,咱们晓得 init 过程启动后,会解析 init.rc 文件,而后创立和加载 "service" 字段指定的过程。zygote 过程就是以这种形式被 init 过程加载的。

system/core/rootdir/init.rc 中,能够看到:

// system/core/rootdir/init.rcimport /init.environ.rcimport /init.usb.rcimport /init.${ro.hardware}.rcimport /vendor/etc/init/hw/init.${ro.hardware}.rcimport /init.usb.configfs.rcimport /init.${ro.zygote}.rc    // ${ro.zygote} 由厂商定义,与平台相干

1.2 init.xx.rc

在不同的平台(32、64 及 64_32)上,init.rc 将蕴含不同的 zygote.rc 文件。

system/core/rootdir 目录下:

init.zygote32_64.rcinit.zyote64.rcinit.zyote32.rcinit.zygote64_32.rc 四个文件。

init.zygote32.rc

zygote 过程对应的执行程序是 app_process (纯 32bit 模式)

init.zygote64.rc

zygote 过程对应的执行程序是 app_process64 (纯 64bit 模式)

init.zygote32_64.rc

启动两个 zygote 过程 (zygote 和 zygote_secondary),对应的执行程序别离是 app_process32 (主模式)、app_process64

init.zygote64_32.rc

启动两个 zygote 过程 (zygote 和 zygote_secondary),对应的执行程序别离是 app_process64 (主模式)、app_process32

那么,为什么要定义这么多种状况?

这次要是因为 Android 5.0 当前开始反对 64 位程序,为了兼容 32 位和 64 位才这样定义。不同的 zygote.rc 内容大致相同,次要区别体现在启动的是 32 位,还是 64 位的过程。init.zygote32_64.rcinit.zygote64_32.rc 会启动两个过程,且存在主次之分。

这里拿 64 位处理器为例,init.zygote64_32.rc 的代码如下所示:

/*  * 过程名称是 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 reserved_disk    socket zygote stream 660 root system                     // 创立一个 socket,名字叫 zygote    socket usap_pool_primary stream 660 root system    onrestart write /sys/android_power/request_state wake    // onrestart 指当过程重启时执行前面的命令    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_secondaryservice 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 reserved_disk    socket zygote_secondary stream 660 root system    socket usap_pool_secondary stream 660 root system    onrestart restart zygote    writepid /dev/cpuset/foreground/tasks

1.3 start zygote

既然定义了此 service 用于启动 Zygote,那么是在什么中央启动的呢?在探讨 init 的时候,咱们剖析过:init 过程启动的最初,会解决 late-init 事件。

// system/core/init/init.cppint SecondStageMain(int argc, char** argv) {    // Don't mount filesystems or start core system services in charger mode.    std::string bootmode = GetProperty("ro.bootmode", "");    if (bootmode == "charger") {        am.QueueEventTrigger("charger");    } else {        am.QueueEventTrigger("late-init");    }    return 0;}

对应于 init.rc 配置文件中,咱们找到如下代码:

// system/core/rootdir/init.rc# Mount filesystems and start core system services.on late-init    ... ...    # Now we can start zygote for devices with file based encryption    trigger zygote-start        // 触发了 zygote-start 事件后,就会启动 zygote 过程    ... ...# 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 对应的映射关系定义于 /system/core/init/builtins.cpp 中    start zygote  // 调用 start 对应的处理函数,启动名为 zygote 的服务(传入前文 init.zygote.rc 中定义的参数)    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_secondaryon 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

start 命令有一个对应的执行函数 do_start() ,定义在 /system/core/init/builtins.cpp 中。

// system/core/init/builtins.cpp// Builtin-function-map startconst BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {    constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();    // clang-format off    static const Map builtin_functions = {        ... ...        {"start",                   {1,     1,    {false,  do_start}}},        ... ...    };    // clang-format on    return builtin_functions;}

咱们看下 do_start()

// system/core/init/builtins.cppstatic Result<Success> do_start(const BuiltinArguments& args) {    Service* svc = ServiceList::GetInstance().FindService(args[1]);    // 找到 zygote service 对应信息    if (!svc) return Error() << "service " << args[1] << " not found";    if (auto result = svc->Start(); !result) {                         // 启动对应的过程        return Error() << "Could not start service: " << result.error();    }    return Success();}

do_start() 首先是通过 FindService()service 数组 中遍历,依据名字匹配出对应的 service,而后调用 service 的 Start() 函数。

最初,咱们来看看 service.cpp 中定义 Start() 函数:

// system/core/init/service.cppResult<Success> Service::Start() {    ... ...    pid_t pid = -1;    if (namespace_flags_) {        pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);    } else {        pid = fork();    // 从 init 过程中,fork 出 zygote 过程    }    ... ...}

Start() 函数次要是 fork 出一个新过程,而后执行 service 对应的二进制文件,并将参数传递进去,上面咱们以 init.zygote64.rc 为例进行剖析。


二、app_process

init.zygote64.rc 启动文件的地址为 /system/bin/app_process64

app_process64 对应的代码定义在 frameworks/base/cmds/app_process目录下。

咱们来看看对应的 Android.mk

// frameworks/base/cmds/app_processLOCAL_PATH:= $(call my-dir)... ...app_process_src_files := \    app_main.cpp \... ...LOCAL_MODULE:= app_processLOCAL_MULTILIB := bothLOCAL_MODULE_STEM_32 := app_process32LOCAL_MODULE_STEM_64 := app_process64... ...

其实不论是 app_processapp_process32 还是 app_process64,对应的源文件都是 app_main.cpp

接下来咱们就看看 app_process 对应的 main 函数,该函数定义于 app_main.cpp 中。

2.1 app_main.main()

app_main.cppmain() 函数中,次要做的事件就是 参数解析。这个函数有 两种 启动模式:

zygote 模式,也就是初始化 zygote 过程,传递的参数有 "--start-system-server --socket-name=zygote",前者示意启动 SystemServer,后者指定 socket 的名称。

application 模式,也就是启动一般应用程序,传递的参数有 "class 名字"以及 "class 带的参数"。

两者最终都是调用 AppRuntime 对象start() 函数,加载 ZygoteInitRuntimeInit 两个 Java 类,并将之前整顿的参数传入进去。

接下来正式开始 main 函数的剖析。

// frameworks/base/cmds/app_process/app_main.cppint main(int argc, char* const argv[]){    // 将参数 argv 放到 argv_String 字符串中,而后打印进去    // 之前 start zygote 传入的参数是 -Xzygote /system/bin --zygote --start-system-server    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 定义于 app_main.cpp 中,继承自 AndroidRuntime    // 就是对 Android 运行环境的一种形象,相似于 java 虚拟机对 Java 程序的作用    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));    argc--;    argv++;    // 这两个参数是 Java 程序须要依赖的 Jar 包,相当于 import    const char* spaced_commands[] = { "-cp", "-classpath" };    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) {          // 比拟参数是否是 spaced_commands 中的参数          if (strcmp(argv[i], spaced_commands[j]) == 0) {            known_command = true;            ALOGV("app_process main found known command '%s'", argv[i]);          }        }        // 如果参数第一个字符是'-',间接跳出循环,之前传入的第一个参数是 -Xzygote,所以执行到这儿就跳出了        if (argv[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]);    }    // 从这里其实能够看出,通过 app_main 能够启动 zygote、system-server 及一般 apk 过程    bool zygote = false;    bool startSystemServer = false;    bool application = false;    String8 niceName;     // app_process 的名称改为 zygote    String8 className;    // 启动 apk 过程时,对应的类名    ++i;    // 跳过一个参数,之前跳过了 -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) {            startSystemServer = true;          // init.zygote.rc 中定义,启动 zygote 后会启动 system-server        } else if (strcmp(arg, "--application") == 0) {            application = true;                // 示意是 application 启动模式,也就是一般应用程序        } else if (strncmp(arg, "--nice-name=", 12) == 0) {            niceName.setTo(arg + 12);          // 过程别名,能够本人指定过程名        } else if (strncmp(arg, "--", 2) != 0) {            className.setTo(arg);              // 与 --application 配置,启动指定的类,application 启动的 class            break;        } else {            --i;            break;        }    }    // 筹备参数    Vector<String8> args;    if (!className.isEmpty()) {      // className 不为空,阐明是 application 启动模式        args.add(application ? String8("application") : String8("tool"));        runtime.setClassNameAndArgs(className, argc - i, argv + i);        ... ...    } 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];         // 获取平台对应的 abi 信息        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=");    // 参数须要制订 abi        abiFlag.append(prop);        args.add(abiFlag);                 // 退出 --abi-list= 参数        for (; i < argc; ++i) {            args.add(String8(argv[i]));    // 将剩下的参数退出 args        }    }    if (!niceName.isEmpty()) {             // 将 app_process 的过程名,替换为 niceName        runtime.setArgv0(niceName.string(), true /* setProcName */);    }    if (zygote) {                          // 调用 Runtime 的 start 函数, 启动 ZygoteInit        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);    } else if (className) {                // 启动 zygote 没有进入这个分支        // 但这个分支阐明,通过配置 init.rc 文件,其实是能够不通过 zygote 来启动一个过程,        // 如果是 application 启动模式,则加载 RuntimeInit。        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);    } else {        // error 状况        fprintf(stderr, "Error: no class name or --zygote supplied.\n");        app_usage();        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");    }}

当初咱们晓得 Zygote 是通过 runtime.start() 函数启动,此处的 runtimeAppRuntime

2.2 AndroidRuntime

因为 AppRuntime 继承自 AndroidRuntime,且没有重写 start() 办法,因而 zygote 的流程进入到了 AndroidRuntime.cpp

// frameworks/base/cmds/app_process/app_main.cppclass AppRuntime : public AndroidRuntime{public:    AppRuntime(char* argBlockStart, const size_t argBlockLength)        : AndroidRuntime(argBlockStart, argBlockLength)        , mClass(NULL)    {    }    ... ...}

接下来,咱们来看看 AndroidRuntime.start() 函数的流程。

2.2.1 创立 Java 虚拟机

// frameworks/base/core/jni/AndroidRuntime.cppvoid 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;    // 创立虚拟机,其中大多数参数由零碎属性决定,最终 startVm 利用 JNI_CreateJavaVM 创立出虚拟机    if (startVm(&mJavaVM, &env, zygote) != 0) {        return;    }    // 回调 AppRuntime 的 onVmCreated 函数    // 对于 zygote 过程的启动流程而言,无实际操作,示意虚构创立实现,然而外面是空实现    onVmCreated(env);    ... ...}

2.2.2 注册 JNI 函数

// frameworks/base/core/jni/AndroidRuntime.cppvoid AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){    ... ...    /* 01. 创立 Java 虚拟机 */    /*     * Register android functions.     */    if (startReg(env) < 0) {         // 注册 JNI 函数        ALOGE("Unable to register all android natives\n");        return;    }    ... ...}

startReg() 首先是设置了 Android 创立线程的处理函数,而后创立了一个 200 容量的部分援用作用域,用于确保不会呈现 OutOfMemoryException,最初就是调用 register_jni_procs() 进行 JNI 注册。

咱们跟进源码看下:

// frameworks/base/core/jni/AndroidRuntime.cpp/*static*/ int AndroidRuntime::startReg(JNIEnv* env){    ATRACE_NAME("RegisterAndroidNatives");    // 定义 Android 创立线程的 func:javaCreateThreadEtc,这个函数外部是通过 Linux 的 clone 来创立线程的    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);           ALOGV("--- registering native functions ---\n");    env->PushLocalFrame(200);    // 创立一个 200 容量的部分援用作用域,这个部分援用其实就是局部变量    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {    // 注册 JNI 函数        env->PopLocalFrame(NULL);        return -1;    }    env->PopLocalFrame(NULL);    // 开释部分援用作用域    return 0;}

从上述代码能够看出,startReg() 函数中次要是通过 register_jni_procs()注册 JNI 函数。其中,gRegJNI 是一个全局数组,该数组的定义如下:

// frameworks/base/core/jni/AndroidRuntime.cppstatic const RegJNIRec gRegJNI[] = {    // 外面就是一堆函数指针    REG_JNI(register_com_android_internal_os_RuntimeInit),    REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),    REG_JNI(register_android_os_SystemClock),    REG_JNI(register_android_util_EventLog),    REG_JNI(register_android_util_Log),    ... ...};

咱们挑一个 register_com_android_internal_os_ZygoteInit_nativeZygoteInit,这实际上是自定义 JNI 函数并进行 动静注册 的规范写法。

外部是调用 JNI 的 RegisterNatives,这样注册后,Java 类 ZygoteInitnative 办法 nativeZygoteInit 就会调用 com_android_internal_os_ZygoteInit_nativeZygoteInit 函数。

// frameworks/base/core/jni/AndroidRuntime.cppint register_com_android_internal_os_ZygoteInit_nativeZygoteInit(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));}

REG_JNI 对应的 宏定义RegJNIRec 构造体的定义为:

#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 将失去函数名;定义 RegJNIRec 数组时,函数名被赋值给 RegJNIRec 构造体,于是每个函数名被强行转换为函数指针

因而,register_jni_procs()参数 就是一个 函数指针数组数组的大小JNIEnv

咱们来跟进一下 register_jni_procs() 函数:

// frameworks/base/core/jni/AndroidRuntime.cppstatic 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) {    // 调用 mProc#ifndef NDEBUG            ALOGD("----------!!! %s failed to load\n", array[i].mName);#endif            return -1;        }    }    return 0;}

联合后面的剖析,容易晓得 register_jni_procs() 函数,实际上就是调用 函数指针(mProc)对应的函数,以进行理论的 JNI 函数注册`。

2.2.3 反射启动 ZygoteInit

持续剖析 AndroidRuntime.cppstart 函数:

// frameworks/base/core/jni/AndroidRuntime.cppvoid AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){    /* 01. 创立 Java 虚拟机*/    /* 02. 注册 JNI 函数 */    --- --- --- --- --- --- ---    // 替换 string 为理论门路    // 例如:将 "com.android.internal.os.ZygoteInit" 替换为 "com/android/internal/os/ZygoteInit"    char* slashClassName = toSlashClassName(className != NULL ? 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");    // 通过反射找到 ZygoteInit 的 main 函数        if (startMeth == NULL) {            ALOGE("JavaVM unable to find main() in '%s'\n", className);            /* keep going */        } else {            env->CallStaticVoidMethod(startClass, startMeth, strArray);    // 调用 ZygoteInit 的 main() 函数            ... ...        }    }    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");}

main() 函数最初,将 通过反射调用 ZygoteInit 的 main() 办法

至此,zygote 过程正式进入了 java 世界。

其实咱们认真想一想,就会感觉 zygote 的整个流程实际上是十分符合实际状况的。

      1、在 Android 中,每个过程都运行在对应的虚拟机上,因而 zygote 首先就负责创立出虚拟机。
      2、而后,为了反射调用 java 代码,必须有对应的 JNI 函数,于是 zygote 进行了 JNI 函数的注册。
      3、当所有筹备得当后,zygote 过程才进入到了 java 世界。


三、ZygoteInit

当初咱们跟进 ZygoteInitmain() 函数。

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.javapublic class ZygoteInit {    ... ...    public static void main(String argv[]) {        ZygoteServer zygoteServer = new ZygoteServer();    // 创立 ZygoteServer 对象                    // 调用 native 函数,确保以后没有其它线程在运行,次要还是处于平安的思考        ZygoteHooks.startZygoteNoThreadCreation();        ... ...        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]);                }            }            final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);            if (abiList == null) {                throw new RuntimeException("No ABI list supplied.");            }                        if (!enableLazyPreload) {                bootTimingsTraceLog.traceBegin("ZygotePreload");                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                        SystemClock.uptimeMillis());                preload(bootTimingsTraceLog);    // 默认状况,预加载信息                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                        SystemClock.uptimeMillis());                bootTimingsTraceLog.traceEnd(); // ZygotePreload            } else {                // 提早预加载,变更 Zygote 过程优先级为 NORMAL 级别,第一次 fork 时才会 preload                Zygote.resetNicePriority();            }            ... ...            if (startSystemServer) {                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);    // fork systemserver                if (r != null) {                    r.run();                    return;                }            }            Log.i(TAG, "Accepting command socket connections");            caller = zygoteServer.runSelectLoop(abiList);    // zygote 过程进入有限循环,解决申请        } catch (Throwable ex) {            throw ex;        } finally {            zygoteServer.closeServerSocket();        }        if (caller != null) {            caller.run();        }    }}

Zygote.main() 函数除了平安相干的内容外,最次要的工作就是 注册 server socket预加载启动 systemserver进入有限循环解决申请音讯

3.1 预加载

咱们看看 预加载 的逻辑:

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.javapublic class ZygoteInit {    static void preload(TimingsTraceLog bootTimingsTraceLog) {        beginPreload();        preloadClasses();            // 读取文件 system/etc/preloaded-classes,而后通过反射加载对应的类        cacheNonBootClasspathClassLoaders();        preloadResources();          // 负责加载一些罕用的系统资源        nativePreloadAppProcessHALs();        maybePreloadGraphicsDriver();        preloadSharedLibraries();    // 一些必要库        preloadTextResources();      // 语言相干的字符信息        WebViewFactory.prepareWebViewInZygote();        endPreload();        warmUpJcaProviders();        // 平安相干的        sPreloadComplete = true;    }}

为了让零碎理论运行时更加晦涩,在 zygote 启动时候,调用 preload() 函数进行了一些 预加载操作

Android 通过 Zygote fork 的形式创立 子过程。Zygote 过程预加载这些类和资源,在 fork 子过程时,仅须要做一个复制即可。这样能够节约子过程的启动工夫。

同时,依据 fork 的 copy-on-write 机制,有些类如果不做扭转,甚至都不必复制,子过程能够和父过程共享这部分数据,从而省去不少内存的占用。

3.2 启动 SystemServer 过程

再来看看启动 SystemServer 的流程:

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.javapublic class ZygoteInit {    private static Runnable forkSystemServer(String abiList, String socketName,            ZygoteServer zygoteServer) {        long capabilities = posixCapabilitiesAsBits(                OsConstants.CAP_IPC_LOCK,                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_PTRACE,                OsConstants.CAP_SYS_TIME,                OsConstants.CAP_SYS_TTY_CONFIG,                OsConstants.CAP_WAKE_ALARM,                OsConstants.CAP_BLOCK_SUSPEND        );        ... ...        /* Hardcoded command line to start the system server */        String args[] = {                "--setuid=1000",                "--setgid=1000",                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",                "--capabilities=" + capabilities + "," + capabilities,                "--nice-name=system_server",                "--runtime-args",                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,                "com.android.server.SystemServer",        };        ZygoteArguments parsedArgs = null;        int pid;        try {            // 将下面筹备的参数,依照 ZygoteArguments 的格调进行封装            parsedArgs = new ZygoteArguments(args);            Zygote.applyDebuggerSystemProperty(parsedArgs);            Zygote.applyInvokeWithSystemProperty(parsedArgs);            boolean profileSystemServer = SystemProperties.getBoolean(                    "dalvik.vm.profilesystemserver", false);            if (profileSystemServer) {                parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;            }            /* Request to fork the system server process */            pid = Zygote.forkSystemServer(            // 通过 fork "决裂" 出 system_server                    parsedArgs.mUid, parsedArgs.mGid,                    parsedArgs.mGids,                    parsedArgs.mRuntimeFlags,                    null,                    parsedArgs.mPermittedCapabilities,                    parsedArgs.mEffectiveCapabilities);        } catch (IllegalArgumentException ex) {            throw new RuntimeException(ex);        }        /* For child process */        if (pid == 0) {            if (hasSecondZygote(abiList)) {    // 解决 32_64 和 64_32 的状况                waitForSecondaryZygote(socketName);            }            // fork 时会 copy socket,system server 须要被动敞开            zygoteServer.closeServerSocket();            return handleSystemServerProcess(parsedArgs);        }        return null;    }}

3.3 解决申请信息

创立出 SystemServer 过程后,调用 ZygoteServer.runSelectLoop(),解决 server socket 收到的命令

// frameworks/base/core/java/com/android/internal/os/ZygoteServer.javaclass ZygoteServer {    Runnable runSelectLoop(String abiList) {        ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();        socketFDs.add(mZygoteSocket.getFileDescriptor());    // 首先将 server socket 退出到 socketFDs        peers.add(null);        while (true) {            fetchUsapPoolPolicyPropsWithMinInterval();                        int[] usapPipeFDs = null;            StructPollfd[] pollFDs = null;    // 每次循环,都从新创立须要监听的 pollFds                    ... ...            int pollIndex = 0;            for (FileDescriptor socketFD : socketFDs) {                pollFDs[pollIndex] = new StructPollfd();                pollFDs[pollIndex].fd = socketFD;                pollFDs[pollIndex].events = (short) POLLIN;    // 关注事件到来                ++pollIndex;            }            ... ...            try {                Os.poll(pollFDs, -1);    // 期待事件到来            } catch (ErrnoException ex) {                throw new RuntimeException("poll failed", ex);            }            boolean usapPoolFDRead = false;                        // 留神这里是倒序的,即优先解决已建设链接的信息,后处理新建链接的申请            while (--pollIndex >= 0) {                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {                    continue;                }                // server socket 最先退出 fds, 因而这里是 server socket 收到数据                if (pollIndex == 0) {                    // Zygote server socket                    // 收到新的建设通信的申请,建设通信连贯                    ZygoteConnection newPeer = acceptCommandPeer(abiList);                    // 退出到 peers 和 socketFDs, 即下一次也开始监听                    peers.add(newPeer);                    socketFDs.add(newPeer.getFileDescriptor());                } else if (pollIndex < usapPoolEventFDIndex) {                    ... ... // 其余通信连贯收到数据                }            }            ... ...        }    }}

从下面代码可知,初始时 socketFDs 中仅有 server socket,因而当有数据到来时,将执行 i 等于 0 的分支。此时,显然是须要创立新的通信连贯,因而 acceptCommandPeer() 将被调用。

咱们看看 acceptCommandPeer() 办法:

// frameworks/base/core/java/com/android/internal/os/ZygoteServer.javaclass ZygoteServer {    private ZygoteConnection acceptCommandPeer(String abiList) {        try {            // socket 编程中,accept() 调用次要用在基于连贯的套接字类型,            // 比方 SOCK_STREAM 和 SOCK_SEQPACKET,它提取出所监听套接字的期待连贯队列中第一个连贯申请,            // 创立一个新的套接字,并返回指向该套接字的文件描述符,新建设的套接字不在监听状态,            // 原来所监听的套接字的状态也不受 accept() 调用的影响。            return createNewConnection(mZygoteSocket.accept(), abiList);        } catch (IOException ex) {            throw new RuntimeException(                    "IOException during accept()", ex);        }    }    protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList)            throws IOException {        return new ZygoteConnection(socket, abiList);    }}

从下面的代码,能够看出 acceptCommandPeer() 调用了 mZygoteSocket.accpet 函数。于是当新的连贯建设时,zygote 将会创立出一个 新的 socket 与其通信,并将该 socket 退出到 socketFDs 中。因而,一旦通信连贯建设后,socketFDs 中将会蕴含有多个 socket

poll 监听到这一组 sockets 上有数据到来时,就会从阻塞中复原,于是咱们须要判断到底是哪个 socket 收到了数据。

四、总结

Zygote 启动流程到此结束,共做了如下几件事:

✎  1. 创立 AppRuntime 并调用其 start() 办法,启动 Zygote 过程。
✎  2. 创立 JavaVM 并为 JavaVM 注册 JNI
✎  3. 通过 JNI 调用 ZygoteInitmain() 函数进入 Zygote 的 Java 层
✎  4. 通过 registerZygoteSocket() 函数创立 服务端 Socket,预加载类和资源,并通过 runSelectLoop() 函数期待如 ActivityManagerService 等的申请。
✎  5. 启动 SystemServer 过程。