Zygote 是Android第一个应用进程,它由init程序解析import /init.${ro.zygote}.rc 所启动。
ro.zygote32.rc

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    writepid /dev/cpuset/foreground/tasks

看到它的启动由app_process 执行文件启动,接下来分析app_process源码:frameworks/base/cmds/app_process/app_main.cpp,直接看其的main函数

    Vector 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) {            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()) {        runtime.setArgv0(niceName.string());        set_process_name(niceName.string());    }    if (zygote) {        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);    } else if (className) {        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);        bool debug = false;        if (debug) {            ALOGD("app_process pid:%d, ppid:%d.", getpid(), getppid());            String8 cmd;            for (int i = 0; i < argc; i++) {                cmd.append(argv[i]);                if (i < argc -1) {                    cmd.append(" ");                }            }            ALOGD("app_process %s.", cmd.string());            FILE* processF = popen("ps >> /data/system/app_process.txt;", "r");            if (processF) {                pclose(processF);            }        }    } 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程序自身或者其他进程,是否需要启动SystemServer进程。Ps: else if 条件分支处系我加的日志。
无论启动的是否为zygote,都执行了Runtime.start函数(frameworks/base/core/jni/AndroidRuntime.cpp 中的start函数),该函数的核心是启动虚拟机实例,并注册androidAPI基础类中的所以native函数,并且反射ZygoteInit类的main函数。

    /* start the virtual machine */    JniInvocation jni_invocation;    jni_invocation.Init(NULL);    JNIEnv* env;    if (startVm(&mJavaVM, &env, zygote) != 0) {        return;    }    onVmCreated(env);    if (startReg(env) < 0) {        ALOGE("Unable to register all android natives\n");        return;    }

现在看启动虚拟机实例的startVM函数

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){    JavaVMInitArgs initArgs;    char propBuf[PROPERTY_VALUE_MAX];    char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];    char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];    char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];    char heapsizeOptsBuf[sizeof("-Xmx")-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 usejitOptsBuf[sizeof("-Xusejit:")-1 + PROPERTY_VALUE_MAX];    char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX];    char jitthresholdOptsBuf[sizeof("-Xjitthreshold:")-1 + PROPERTY_VALUE_MAX];    char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];    char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];    char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];    char cachePruneBuf[sizeof("-Xzygote-max-boot-retry=")-1 + PROPERTY_VALUE_MAX];    char dex2oatXmsImageFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];    char dex2oatXmxImageFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];    char dex2oatXmsFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];    char dex2oatXmxFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];    char dex2oatCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];    char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];    char dex2oatThreadsBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX];    char dex2oatThreadsImageBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX];    char dex2oat_isa_variant_key[PROPERTY_KEY_MAX];    char dex2oat_isa_variant[sizeof("--instruction-set-variant=") -1 + PROPERTY_VALUE_MAX];    char dex2oat_isa_features_key[PROPERTY_KEY_MAX];    char dex2oat_isa_features[sizeof("--instruction-set-features=") -1 + PROPERTY_VALUE_MAX];    char dex2oatFlagsBuf[PROPERTY_VALUE_MAX];    char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];    char extraOptsBuf[PROPERTY_VALUE_MAX];    char voldDecryptBuf[PROPERTY_VALUE_MAX];    enum {      kEMDefault,      kEMIntPortable,      kEMIntFast,      kEMJitCompiler,    } executionMode = kEMDefault;    char profilePeriod[sizeof("-Xprofile-period:")-1 + PROPERTY_VALUE_MAX];    char profileDuration[sizeof("-Xprofile-duration:")-1 + PROPERTY_VALUE_MAX];    char profileInterval[sizeof("-Xprofile-interval:")-1 + PROPERTY_VALUE_MAX];    char profileBackoff[sizeof("-Xprofile-backoff:")-1 + PROPERTY_VALUE_MAX];    char profileTopKThreshold[sizeof("-Xprofile-top-k-threshold:")-1 + PROPERTY_VALUE_MAX];    char profileTopKChangeThreshold[sizeof("-Xprofile-top-k-change-threshold:")-1 +                                    PROPERTY_VALUE_MAX];    char profileType[sizeof("-Xprofile-type:")-1 + PROPERTY_VALUE_MAX];    char profileMaxStackDepth[sizeof("-Xprofile-max-stack-depth:")-1 + PROPERTY_VALUE_MAX];    char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX];    char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];    char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];    char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];    char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];    char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];    char fingerprintBuf[sizeof("-Xfingerprint:") + PROPERTY_VALUE_MAX];    bool checkJni = false;    property_get("dalvik.vm.checkjni", propBuf, "");    if (strcmp(propBuf, "true") == 0) {        checkJni = true;    } else if (strcmp(propBuf, "false") != 0) {        /* property is neither true nor false; fall back on kernel parameter */        property_get("ro.kernel.android.checkjni", propBuf, "");        if (propBuf[0] == '1') {            checkJni = true;        }    }    ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");    if (checkJni) {        /* extended JNI checking */        addOption("-Xcheck:jni");        /* with -Xcheck:jni, this provides a JNI function call trace */        //addOption("-verbose:jni");    }    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;    }    parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");    strcpy(jniOptsBuf, "-Xjniopts:");    if (parseRuntimeOption("dalvik.vm.jniopts", jniOptsBuf, "-Xjniopts:")) {        ALOGI("JNI options: '%s'\n", jniOptsBuf);    }    /* route exit() to our handler */    addOption("exit", (void*) runtime_exit);    /* route fprintf() to our handler */    addOption("vfprintf", (void*) runtime_vfprintf);    /* register the framework-specific "is sensitive thread" hook */    addOption("sensitiveThread", (void*) runtime_isSensitiveThread);    /* enable verbose; standard options are { jni, gc, class } */    //addOption("-verbose:jni");    addOption("-verbose:gc");    //addOption("-verbose:class");    /*     * The default starting and maximum size of the heap.  Larger     * values should be specified in a product property override.     */    parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");    parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");    parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");    parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");    parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");    parseRuntimeOption("dalvik.vm.heaptargetutilization",                       heaptargetutilizationOptsBuf,                       "-XX:HeapTargetUtilization=");    /*     * JIT related options.     */    parseRuntimeOption("dalvik.vm.usejit", usejitOptsBuf, "-Xusejit:");    parseRuntimeOption("dalvik.vm.jitcodecachesize", jitcodecachesizeOptsBuf, "-Xjitcodecachesize:");    parseRuntimeOption("dalvik.vm.jitthreshold", jitthresholdOptsBuf, "-Xjitthreshold:");    property_get("ro.config.low_ram", propBuf, "");    if (strcmp(propBuf, "true") == 0) {      addOption("-XX:LowMemoryMode");    }    parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");    parseRuntimeOption("dalvik.vm.backgroundgctype", backgroundgcOptsBuf, "-XX:BackgroundGC=");    /*     * Enable debugging only for apps forked from zygote.     * Set suspend=y to pause during VM init and use android ADB transport.     */    if (zygote) {      addOption("-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y");    }    parseRuntimeOption("dalvik.vm.lockprof.threshold",                       lockProfThresholdBuf,                       "-Xlockprofthreshold:");    if (executionMode == kEMIntPortable) {        addOption("-Xint:portable");    } else if (executionMode == kEMIntFast) {        addOption("-Xint:fast");    } else if (executionMode == kEMJitCompiler) {        addOption("-Xint:jit");    }    // If we are booting without the real /data, don't spend time compiling.    property_get("vold.decrypt", voldDecryptBuf, "");    bool skip_compilation = ((strcmp(voldDecryptBuf, "trigger_restart_min_framework") == 0) ||                             (strcmp(voldDecryptBuf, "1") == 0));    // Extra options for boot.art/boot.oat image generation.    parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xms", dex2oatXmsImageFlagsBuf,                               "-Xms", "-Ximage-compiler-option");    parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xmx", dex2oatXmxImageFlagsBuf,                               "-Xmx", "-Ximage-compiler-option");    if (skip_compilation) {        addOption("-Ximage-compiler-option");        addOption("--compiler-filter=verify-none");    } else {        parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,                            "--compiler-filter=", "-Ximage-compiler-option");    }    // Make sure there is a preloaded-classes file.    if (!hasFile("/system/etc/preloaded-classes")) {        ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",              strerror(errno));        return -1;    }    addOption("-Ximage-compiler-option");    addOption("--image-classes=/system/etc/preloaded-classes");    // If there is a compiled-classes file, push it.    if (hasFile("/system/etc/compiled-classes")) {        addOption("-Ximage-compiler-option");        addOption("--compiled-classes=/system/etc/compiled-classes");    }    property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");    parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");    // Extra options for DexClassLoader.    parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xms", dex2oatXmsFlagsBuf,                               "-Xms", "-Xcompiler-option");    parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xmx", dex2oatXmxFlagsBuf,                               "-Xmx", "-Xcompiler-option");    if (skip_compilation) {        addOption("-Xcompiler-option");        addOption("--compiler-filter=verify-none");        // We skip compilation when a minimal runtime is brought up for decryption. In that case        // /data is temporarily backed by a tmpfs, which is usually small.        // If the system image contains prebuilts, they will be relocated into the tmpfs. In this        // specific situation it is acceptable to *not* relocate and run out of the prebuilts        // directly instead.        addOption("--runtime-arg");        addOption("-Xnorelocate");    } else {        parseCompilerOption("dalvik.vm.dex2oat-filter", dex2oatCompilerFilterBuf,                            "--compiler-filter=", "-Xcompiler-option");    }    parseCompilerOption("dalvik.vm.dex2oat-threads", dex2oatThreadsBuf, "-j", "-Xcompiler-option");    parseCompilerOption("dalvik.vm.image-dex2oat-threads", dex2oatThreadsImageBuf, "-j",                        "-Ximage-compiler-option");    // The runtime will compile a boot image, when necessary, not using installd. Thus, we need to    // pass the instruction-set-features/variant as an image-compiler-option.    // TODO: Find a better way for the instruction-set.#if defined(__arm__)    constexpr const char* instruction_set = "arm";#elif defined(__aarch64__)    constexpr const char* instruction_set = "arm64";#elif defined(__mips__) && !defined(__LP64__)    constexpr const char* instruction_set = "mips";#elif defined(__mips__) && defined(__LP64__)    constexpr const char* instruction_set = "mips64";#elif defined(__i386__)    constexpr const char* instruction_set = "x86";#elif defined(__x86_64__)    constexpr const char* instruction_set = "x86_64";#else    constexpr const char* instruction_set = "unknown";#endif    // Note: it is OK to reuse the buffer, as the values are exactly the same between    //       * compiler-option, used for runtime compilation (DexClassLoader)    //       * image-compiler-option, used for boot-image compilation on device    // Copy the variant.    sprintf(dex2oat_isa_variant_key, "dalvik.vm.isa.%s.variant", instruction_set);    parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant,                        "--instruction-set-variant=", "-Ximage-compiler-option");    parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant,                        "--instruction-set-variant=", "-Xcompiler-option");    // Copy the features.    sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set);    parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,                        "--instruction-set-features=", "-Ximage-compiler-option");    parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,                        "--instruction-set-features=", "-Xcompiler-option");    property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, "");    parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option");    /* extra options; parse this late so it overrides others */    property_get("dalvik.vm.extra-opts", extraOptsBuf, "");    parseExtraOpts(extraOptsBuf, NULL);    /* Set the properties for locale */    {        strcpy(localeOption, "-Duser.locale=");        const std::string locale = readLocale();        strncat(localeOption, locale.c_str(), PROPERTY_VALUE_MAX);        addOption(localeOption);    }    /*     * Set profiler options     */    // Whether or not the profiler should be enabled.    property_get("dalvik.vm.profiler", propBuf, "0");    if (propBuf[0] == '1') {        addOption("-Xenable-profiler");    }    // Whether the profile should start upon app startup or be delayed by some random offset    // (in seconds) that is bound between 0 and a fixed value.    property_get("dalvik.vm.profile.start-immed", propBuf, "0");    if (propBuf[0] == '1') {        addOption("-Xprofile-start-immediately");    }    // Number of seconds during profile runs.    parseRuntimeOption("dalvik.vm.profile.period-secs", profilePeriod, "-Xprofile-period:");    // Length of each profile run (seconds).    parseRuntimeOption("dalvik.vm.profile.duration-secs",                       profileDuration,                       "-Xprofile-duration:");    // Polling interval during profile run (microseconds).    parseRuntimeOption("dalvik.vm.profile.interval-us", profileInterval, "-Xprofile-interval:");    // Coefficient for period backoff.  The the period is multiplied    // by this value after each profile run.    parseRuntimeOption("dalvik.vm.profile.backoff-coeff", profileBackoff, "-Xprofile-backoff:");    // Top K% of samples that are considered relevant when    // deciding if the app should be recompiled.    parseRuntimeOption("dalvik.vm.profile.top-k-thr",                       profileTopKThreshold,                       "-Xprofile-top-k-threshold:");    // The threshold after which a change in the structure of the    // top K% profiled samples becomes significant and triggers    // recompilation. A change in profile is considered    // significant if X% (top-k-change-threshold) of the top K%    // (top-k-threshold property) samples has changed.    parseRuntimeOption("dalvik.vm.profile.top-k-ch-thr",                       profileTopKChangeThreshold,                       "-Xprofile-top-k-change-threshold:");    // Type of profile data.    parseRuntimeOption("dalvik.vm.profiler.type", profileType, "-Xprofile-type:");    // Depth of bounded stack data    parseRuntimeOption("dalvik.vm.profile.stack-depth",                       profileMaxStackDepth,                       "-Xprofile-max-stack-depth:");    /*     * Tracing options.     */    property_get("dalvik.vm.method-trace", propBuf, "false");    if (strcmp(propBuf, "true") == 0) {        addOption("-Xmethod-trace");        parseRuntimeOption("dalvik.vm.method-trace-file",                           methodTraceFileBuf,                           "-Xmethod-trace-file:");        parseRuntimeOption("dalvik.vm.method-trace-file-siz",                           methodTraceFileSizeBuf,                           "-Xmethod-trace-file-size:");        property_get("dalvik.vm.method-trace-stream", propBuf, "false");        if (strcmp(propBuf, "true") == 0) {            addOption("-Xmethod-trace-stream");        }    }    // Native bridge library. "0" means that native bridge is disabled.    property_get("ro.dalvik.vm.native.bridge", propBuf, "");    if (propBuf[0] == '\0') {        ALOGW("ro.dalvik.vm.native.bridge is not expected to be empty");    } else if (strcmp(propBuf, "0") != 0) {        snprintf(nativeBridgeLibrary, sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX,                 "-XX:NativeBridge=%s", propBuf);        addOption(nativeBridgeLibrary);    }#if defined(__LP64__)    const char* cpu_abilist_property_name = "ro.product.cpu.abilist64";#else    const char* cpu_abilist_property_name = "ro.product.cpu.abilist32";#endif  // defined(__LP64__)    property_get(cpu_abilist_property_name, propBuf, "");    if (propBuf[0] == '\0') {        ALOGE("%s is not expected to be empty", cpu_abilist_property_name);        return -1;    }    snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf);    addOption(cpuAbiListBuf);    // Dalvik-cache pruning counter.    parseRuntimeOption("dalvik.vm.zygote.max-boot-retry", cachePruneBuf,                       "-Xzygote-max-boot-retry=");    /*     * When running with debug.generate-debug-info, add --generate-debug-info to     * the compiler options so that the boot image, if it is compiled on device,     * will include native debugging information.     */    property_get("debug.generate-debug-info", propBuf, "");    if (strcmp(propBuf, "true") == 0) {        addOption("-Xcompiler-option");        addOption("--generate-debug-info");        addOption("-Ximage-compiler-option");        addOption("--generate-debug-info");    }    /*     * Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will     * contain the fingerprint and can be parsed.     */    parseRuntimeOption("ro.build.fingerprint", fingerprintBuf, "-Xfingerprint:");    initArgs.version = JNI_VERSION_1_4;    initArgs.options = mOptions.editArray();    initArgs.nOptions = mOptions.size();    initArgs.ignoreUnrecognized = JNI_FALSE;    /*     * Initialize the VM.     *     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.     * If this call succeeds, the VM is ready, and we can start issuing     * JNI calls.     */    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {        ALOGE("JNI_CreateJavaVM failed\n");        return -1;    }    return 0;}

函数这么长,挑拣几个重要的描述:
dalvik.vm.checkjni:检测jni选项,会影响jni运行速度
dalvik.vm.execution-mode:虚拟机解释器模式:可移植、快速解释、即时编译Just-in-time
dalvik.vm.stack-trace-file:虚拟机traces文件路径,如果应用程序anr无响应会生成此文件,通常为/data/anr/traces.txt
dalvik.vm.heapstartsize:虚拟机堆内存启动大小
dalvik.vm.heapsize:虚拟机堆大小
dalvik.vm.heapgrowthlimit:堆大小增长限制大小
dalvik.vm.heapminfree/dalvik.vm.heapmaxfree:最小最大堆空闲大小
ro.dalvik.vm.native.bridge:native代码转换桥库,通常在模拟器会有值
其他的就不说明了(看不懂)

解析解析完这些参数开始启动虚拟机了
通过读取persist.sys.dalvik.vm.lib.2的内容判断启动的是dalvik虚拟机还是art虚拟机。

虚拟机启动完成之后开始反射ZygoteInitJava类的main函数

    public static void main(String argv[]) {        try {            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])) {                    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.");            }            registerZygoteSocket(socketName);//创建ZygoteSocket            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                SystemClock.uptimeMillis());            preload();//加载预加载的类,资源,共享库等            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                SystemClock.uptimeMillis());            // Finish profiling the zygote initialization.            SamplingProfilerIntegration.writeZygoteSnapshot();            // Do an initial gc to clean up after startup            gcAndFinalize();//释放且回收一次内存            // Disable tracing so that forked processes do not inherit stale tracing tags from            // Zygote.            Trace.setTracingEnabled(false);            if (startSystemServer) { //是否启动系统服务                startSystemServer(abiList, socketName);            }            Log.i(TAG, "Accepting command socket connections");            runSelectLoop(abiList);//开始不断的轮询,等待ams到进程创建消息来fork子进程            closeServerSocket();        } catch (MethodAndArgsCaller caller) {            caller.run();        } catch (RuntimeException ex) {            Log.e(TAG, "Zygote died with exception", ex);            closeServerSocket();            throw ex;        }    }

通过之前传递的参数可得知需要启动SystemServer,

long capabilities = posixCapabilitiesAsBits(            OsConstants.CAP_BLOCK_SUSPEND,            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        );        /* 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,1032,3001,3002,3003,3006,3007",            "--capabilities=" + capabilities + "," + capabilities,            "--nice-name=system_server",            "--runtime-args",            "com.android.server.SystemServer",        };

这是参数属性,足以让SystemServer掌控整个android系统(天命之子)。
关注到args最后一个参数,后续肯定会执行SystemServer来启动android所有服务。这时Zygote.forkSystemServer 将创建名为system_server的进程并将com.android.server.SystemServer传给system_server作为启动类。

接下来执行在system_server的函数handleSystemServerProcess将会被执行到,handleSystemServerProcess将会调用RuntimeInit.java的zygoteInit方法

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)            throws ZygoteInit.MethodAndArgsCaller {        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");        redirectLogStreams(); //重定向System.out/err 内容到Log设备        commonInit();        nativeZygoteInit();        applicationInit(targetSdkVersion, argv, classLoader);     }

applicationInit(targetSdkVersion, argv, classLoader); //开始真正的调用SystemServer中的main函数,这是它的任务已经完成。

之前app_process除了能启动Zygote还可以启动其他应用程序
直接查看RuntimeInit的main函数

    public static final void main(String[] argv) {        enableDdms();        if (argv.length == 2 && argv[1].equals("application")) {            if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application");            redirectLogStreams();         } else {            if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting tool");        }        commonInit();        /*         * Now that we're running in interpreted code, call back into native code         * to run the system.         */        nativeFinishInit();        if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");    }

如果是应用,需要重定向System.err/out流到Log设备,commonInit()是时区和http代理到设置等。nativeFinishInit()最终将通过jni调用

/* * Code written in the Java Programming Language calls here from main(). */static void com_android_internal_os_RuntimeInit_nativeFinishInit(JNIEnv* env, jobject clazz){    gCurRuntime->onStarted();}

回到app_main.cpp到虚函数onStarted中。

    virtual void onStarted()    {        sp proc = ProcessState::self();        ALOGV("App process: starting thread pool.\n");        proc->startThreadPool();        AndroidRuntime* ar = AndroidRuntime::getRuntime();        ar->callMain(mClassName, mClass, mArgs);        IPCThreadState::self()->stopProcess();     }

这里调用需要ProcessState来进程binder通讯,直到当前进main函数执行完毕之后才停止进程。常见到使用场景有am,pm 等文件

#!/system/bin/sh## Script to start "am" on the device, which has a very rudimentary# shell.#base=/systemexport CLASSPATH=$base/framework/am.jarexec app_process $base/bin com.android.commands.am.Am "$@"ps >> /data/misc/logd/record.ps //加到调试日志,忽略。

至此整个Zygote分析完成。

更多相关文章

  1. Android下openGL操作矩阵的函数
  2. 简单android Service 创建与启动示例
  3. Android得到视频缩略图
  4. android system services startup process
  5. Android中的设计模式--建造者模式
  6. android开机自启动的后台Service的实现 .
  7. Android(安卓)启动 Launcher
  8. android:获取已经安装软件列表
  9. 箭头函数的基础使用

随机推荐

  1. Android(安卓)Studio 快捷键
  2. Android(一) 安卓概述
  3. Android Mac开发Android推荐软件
  4. android:layout_paddingLeft和android:la
  5. Android(安卓)NDK开发篇(一) windows免cygw
  6. Android引路蜂地图开发包
  7. Android Animation 大全
  8. Android(安卓)led灯实现大致流程
  9. Android客户端post请求服务器端实例
  10. Android中的线程机制