Zygote进程的启动源码阅读

本文基于Android6.0.0系统

从这篇文章到后面的好几篇文章,会阅读从Android系统产生Zygote进程以后到我们点击应用图标启动应用进程这个过程中的源码,这个第一篇我们就来看看Zygote进程是如何被启动的.

我们都知道Android系统是基于Linux系统的,Linux中的所有进程都是有init进程fork出来的,那么Zygote进程也不例外,他也是有init进程fork出来的,这个我们在

\system\core\rootdir\init.zygote64.rc 文件中就可以看得到.

值得一提的是,在之前的Android源码中init文件只有一个,现在的话谷歌程序员将init中的一些操作进行了剥离,如执行创建zygote进程的代码就分为了如下好几个版本,这个应该是针对不同系统所做出的调整.

image.png
1)我们以init.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

这种.rc中的脚本命令的含义我们都可以在\system\core\init\readme.txt文件中找到他的含义 例如service:

Services
--------
Services are programs which init launches and (optionally) restarts
when they exit.  Services take the form of:

service <name> <pathname> [ <argument> ]*
   <option>
   <option>
   ...

1.第一句命令中的意义是 要创建出一个名叫 zygote 的进程,这个进程所要执行的程序就在 /system/bin/app_process目录下, -Xzygote /system/bin --zygote --start-system-server是要传入到app_process程序中的参数

2.第三句的作用是要在上面创建的 zygote进程中 启动一个名叫 zygote 的socket,这个socket就是我们后面用作ActivityManagerService进程和这个zygote进程通信的,主要是请求zygote进程fork出一个新的应用程序进程

3.后面的这几句onRestart...命令都是在zygote进程重启时需要执行的命令

2)后面我们确定到/system/bin/app_process对应的文件就是 \frameworks\base\cmds\app_process\app_main.cpp文件,我们来看看app_main.cpp中都做了什么.
int main(int argc, char* const argv[])
{
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {

    if (errno != EINVAL) {
        LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
        return 12;
    }
}

//创建AppRuntime 变量
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
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]));
}

// 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.
//我们传入和参数包含  "--zygote" 和  "--start-system-server" 所以 zygote 和  startSystemServer  都会被置为true
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) {
        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);
} 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.首先我们要明确一点的是,我们给main函数传递过来的参数中是 -Xzygote /system/bin --zygote --start-system-server.

2.因为参数中包含了 --zygote所以他最后会走 runtime.start("com.android.internal.os.ZygoteInit", args, zygote);这句代码,其实main函数中主要的工作也就是启动创建AppRuntime 这个变量,而且在最后也执行了AppRuntime的start()方法.

3)下面我们在看看AppRuntime中都做了些什么,AppRuntime也是类位于\frameworks\base\cmds\app_process\app_main.cpp文件中,我们可以发现他是继承自AndroidRuntime的,而且在他里面没有找到start()方法,所以就到他的父类AndroidRuntime中找
class AppRuntime : public AndroidRuntime
{
public:
AppRuntime(char* argBlockStart, const size_t argBlockLength)
    : AndroidRuntime(argBlockStart, argBlockLength)
    , mClass(NULL){
}
.....
}
4)AndroidRuntime位于 \frameworks\base\core\jni\AndroidRuntime.cpp中,下面的代码就是start()方法,从注释中看,就可以看出来这个方法主要是负责启动Android Runtime的,而且也会牵扯到调用传入classNamemain 方法去启动虚拟机
 /*
 * Start the Android runtime.  This involves starting the virtual machine
 * and calling the "static void main(String[] args)" method in the class
 * named by "className".
 *
 * Passes the main function two arguments, the class name and the specified
 * options string.
 */
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");

    /*
     * 'startSystemServer == true' means runtime is obsolete and not run from
     * init.rc anymore, so we print out the boot start event here.
     */
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
           /* track our progress through the boot sequence */
           const int LOG_BOOT_PROGRESS_START = 3000;
           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    //注册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.
     */
    //将现有的参数转换成ZygoteInit中main方法需要的String 数组
    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);
    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 {
            //调用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.我们先确认一下,传过来的参数是runtime.start("com.android.internal.os.ZygoteInit", args, zygote);这里的第三个参数zygote经过我们的分析应该是 true
2.这个start()方法主要做了三件事情,
  1)调用startVm()方法启动虚拟机
  2)调用startReg()注册了Android的JNI方法
  3)调用 env->CallStaticVoidMethod(startClass, startMeth, strArray);方法来调用ZygoteInit的main方法来启动SystemServer进程

5)下面我们就来看看ZygoteInit文件的main方法,该文件位于\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
        try {
            //启动DDMS
            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.");
            }
            
            //创建一个Socket用来和ActivityManagerService进行通信
            registerZygoteSocket(socketName);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            //加载类,加载资源,加载OpenGL等
            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);

            //进行SystemServer进程的创建(fork)
            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            Log.i(TAG, "Accepting command socket connections");
            //开启无限循环等待ActivityMangerService发送通知去fork一个新的应用程序进程
            runSelectLoop(abiList);

            //关闭socket
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

1.首先我们在AndroidRuntime中给ZygoteInit中传入的参数会包含"start-system-server"所以**startSystemServer **会被置为true

2.调用 registerZygoteSocket(socketName);来创建一个Socket用来和ActivityManagerService进行通信

    /**
     * Registers a server socket for zygote command connections
     *
     * @throws RuntimeException when open fails
     */
    private static void registerZygoteSocket(String socketName) {
        if (sServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                sServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

3.调用preload()方法去加载一些常用的类,图片,颜色.

    static void preload() {
        Log.d(TAG, "begin preload");
        //加载Android中常用的类
        preloadClasses();
        //加载Android中常用的资源,图片等
        preloadResources();
        //加载openGL
        preloadOpenGL();
        //加载Android中需要的一些类库,如android,jnigraphics,compiler_rt等
        preloadSharedLibraries();
        //初始化Hyphenator(用来显示文字)
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        //初始化WebView(在Zygote进程中初始化是为了达到内存共享的目的)
        WebViewFactory.prepareWebViewInZygote();
        Log.d(TAG, "end preload");
    }

4.调用 startSystemServer(abiList, socketName);来进行fork一个新的进程用来启动SystemServer组件,这也就是我们说的SystemServer进程

    /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        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",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            //新建的进程pid会等于0
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }
  1. 调用 runSelectLoop();开启无限循环等待ActivityMangerService发送通知去fork一个新的应用程序进程
        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }

6.调用RuntimeInit.enableDdms();来启动DDMS

6)在上面第4条我们说过在创建SystemServer进程的时候pid会返回0,那么后续代码自然就会执行handleSystemServerProcess(parsedArgs);我们一起来看看这个方法中都干了什么
 /**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
      
        //因为新创建的进程是在Zygote进程中启动的,所以该进程也会继承那个Socket,这里先将这个socket关闭掉
        closeServerSocket();

        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Os.umask(S_IRWXG | S_IRWXO);

        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            performSystemServerDexOpt(systemServerClasspath);
        }

        if (parsedArgs.invokeWith != null) {
            String[] args = parsedArgs.remainingArgs;
            // If we have a non-null system server class path, we'll have to duplicate the
            // existing arguments and append the classpath to it. ART will handle the classpath
            // correctly when we exec a new process.
            if (systemServerClasspath != null) {
                String[] amendedArgs = new String[args.length + 2];
                amendedArgs[0] = "-cp";
                amendedArgs[1] = systemServerClasspath;
                System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
            }

            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(), null, args);
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */
    }

1.通过分析我们可以看出来这个方法是完成fork完SystemServer进程后的其他工作

2.这个方法中最关键的就是** RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);**这个方法主要是去完成SystemServer进程的启动

7)下面我们看看RuntimeInit.zygoteInit()方法中都干了什么,RuntimeInit文件位于

\android-6.0.0_r1\frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

    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");

        //将 System.out 和 System.err 定向到Android日志中
        redirectLogStreams();

        commonInit();
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }

1.首先我们明确第二个参数中包含了com.android.server.SystemServer这个全类名

2.调用redirectLogStreams();方法将 System.out 和 System.err 定向到Android日志中

4.调用 commonInit();方法做时间,AndroidConfig的初始化

5.调用nativeZygoteInit();这个native方法去初始化一个Binder用来做进程间通信

6.在 applicationInit(targetSdkVersion, argv, classLoader);中调用 invokeStaticMain(args.startClass, args.startArgs, classLoader);这个方法来调用SystemServer这个类的main方法

    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {

            //调用main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }
8)下面我们就看看nativeZygoteInit()方法中做了什么
private static final native void nativeZygoteInit();

我们可以看到他是一个native方法,它对应的实现方法是在 android-6.0.0_r1\frameworks\base\core\jni\AndroidRuntime.cpp文件中

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

gCurRuntime其实就是AndroidRuntime本身

static AndroidRuntime* gCurRuntime = NULL;

然后再去找onZygoteInit()方法,但是我们在AndroidRuntime.cpp文件中没有找到,我们再去AndroidRuntime.h这个头文件去找,发现AndroidRuntime是一个虚拟类,,所以我们需要在他的子类中找实现了的onZygoteInit()方法.

我们知道AppRuntime继承了AndroidRuntime所以我们在APPRuntime中看看,他的文件对应在android-6.0.0_r1\frameworks\base\cmds\app_process\app_main.cpp

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

然后调用了ProcessState的startThreadPool()方法,ProcessState类位于android-6.0.0_r1\frameworks\native\libs\binder\ProcessState.cpp

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

这个方法主要是启动一个线程池,该线程池中的线程主要是负责和binder驱动程序进行交互的,ProcessState是Binder进程间通信的一个基础组件,这里我们就不在深究了,后面我们会仔细分析关于Android IPC的问题这里我们只需要知道nativeZygoteInit()方法就初始化了一个线程池用于和Binder基础组件,这个方法执行完后这个进程的Binder进程间通信基础就准备好了.

9)下面我们看看SystemServer中的main方法都干了什么,SystemServer位于android-6.0.0_r1\frameworks\base\services\java\com\android\server\SystemServer.java
    public static void main(String[] args) {
        new SystemServer().run();
    }

mian方法执行完毕后SystemServer进程就启动了这个会在下面
SystemServer进程启动源码阅读 中分析

10)最后我们在回到5.5中,里面提到会调用ZygoteInit.runSelectLoop()方法开启一个无限循环,等待ActivityManagerService来连接这个socket然后调用ZygoteConnection.runOnce函数来创建新的应用程序进程,后面我们学习到Android启动应用程序的时候会仔细分析.

    /**
     * Runs the zygote process's select loop. Accepts new connections as
     * they happen, and reads commands from connections one spawn-request's
     * worth at a time.
     *
     * @throws MethodAndArgsCaller in a child process when a main() should
     * be executed.
     */
    private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }
11)到这里Zygote进程的启动就完成了,下面是这个流程的时序图
zygote启动流程.png

值得注意的点

1.Android中的进程间通信一般是使用Binder的但是有特例就是zygote进程和SystemServer进程间的通信是使用Socket进行的

2.DDMS ;Android中常用的类和资源 ;OpenGL; android,jnigraphics,compiler_rt类库; WebView都是在ZygoteInit类中的main方法中加载的,其实WebView选择在Zygote进程中初始化是为了达到内存共享的目的

3.系统启动init进程的时候在init进程中会启动一个Zygote进程,Zygote进程负责Android程序框架和其他进程的启动

4.Zygote进程首先会启动一个SystemServer进程,该进程用于启动Android程序中的各种服务,如PackageManagerService等

5.当我们需要新建一个应用程序进程时ActivityManagerService会通过socket进程间通信,通知Zygote去新建一个进程.

6.在AndroidRuntime的main方法中启动了虚拟机,注册了JNI方法

7.Zygote进程在Linux解析init.zygote32.rc中的 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
这句代码的饿时候就已经创建了,后面执行的/system/bin/app_process中的代码都是在该进程中执行的

参考文章

http://blog.csdn.net/luoshengyang/article/details/6768304
http://blog.csdn.net/qq_23547831/article/details/51104873

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容