博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[日更-2019.4.20、21] cm-14.1 Android系统启动过程分析(二)-Zygote进程启动过程
阅读量:5938 次
发布时间:2019-06-19

本文共 24879 字,大约阅读时间需要 82 分钟。

hot3.png

声明

  • 前阶段在项目中涉及到了Android系统定制任务,Android系统定制前提要知道Android系统是如何启动的。
  • 本文参考了一些书籍的若干章节,比如《Android进阶解密-第2章-Android系统启动》、《深入理解Android虚拟机-第8/9/10章-init进程详解/Dalvik VM的进程系统/Dalvik VM运作流程详解》、《深入理解Android系统-第6/7/8章-init启动进程详解/Zygote进程详解/System进程详解》等
  • 本文使用的代码是LineageOS的cm-14.1,对应Android 7.1.2,可以参考我的另一篇博客:
  • 很多代码注释待详细写

0 写在前面的

    Android系统中主要有三个重要的进程系统:

  1. Zygote进程:被称为孵化进程,功能和Linux中的fork类似,不同的是它在Android系统中用来产生Java层的子进程;
  2. System进程:系统进程,是Android Framework所在的进程,用于启动Android系统。核心进程为Zygote进程fork出来的system_server,由system_server再去启动Framework层各个系统服务;
  3. 应用程序进程:每个Android应用程序运行时都有自己的进程;

1 Zygote是什么

    Android系统是基于Linux内核搭建起来的开放系统,那么它也是遵循Linux操作系统的基本原理:即所有的进程都是由init进程fork出来的。Zygote进程也是由init进程根据解析的init.rc相关命令启动起来的。之所以Zygote进程在Android系统中处于重要位置,是因为它是Android系统中第一个Java进程、也是Framework系统服务的祖先,Zygote正是通常所说的Java运行环境(JVM)。

    Zygote在Android系统中是一个C/S架构,其他进程作为客户端向Zygote发出fork请求,当Zygote接收到命令后就fork出一个Activity进程。

    用adb连接Nexus5手机,执行ps命令可观察各个系统进程的PID及PPID:

USER      PID   PPID  VSIZE  RSS   WCHAN            PC  NAMEroot      1     0     7916   1388  sys_epoll_ 00000000 S /initroot      2     0     0      0       kthreadd 00000000 S kthreadd...省略n行...root      227   1     1559616 68852 poll_sched 00000000 S zygote...省略n行...system    806   227   1825696 136184 sys_epoll_ 00000000 S system_serveru0_a64    973   227   993120 48228 sys_epoll_ 00000000 S com.android.inputmethod.latinu0_a33    987   227   1087016 106116 sys_epoll_ 00000000 S com.android.systemuimedia_rw  992   157   8388   1852  inotify_re 00000000 S /system/bin/sdcardu0_a1     1083  227   978064 37988 sys_epoll_ 00000000 S org.cyanogenmod.cmaudio.servicewifi      1124  1     7660   3164  poll_sched 00000000 S /system/bin/wpa_supplicantu0_a7     1408  227   977836 38748 sys_epoll_ 00000000 S com.android.cellbroadcastreceiveru0_a34    1465  227   977348 36624 sys_epoll_ 00000000 S org.cyanogenmod.weather.provideru0_a10    1525  227   976332 37348 sys_epoll_ 00000000 S android.ext.servicesroot      1542  1     11392  1444  futex_wait 00000000 S /system/bin/mpdecisionu0_a47    1595  227   984276 42372 sys_epoll_ 00000000 S com.android.deskclocku0_a31    1637  227   977884 37928 sys_epoll_ 00000000 S org.cyanogenmod.weatherserviceu0_a58    1642  227   982704 39360 sys_epoll_ 00000000 S com.android.printspooleru0_a3     1658  227   981108 39668 sys_epoll_ 00000000 S org.cyanogenmod.audiofxnfc       1673  227   1002016 47588 sys_epoll_ 00000000 S com.android.nfcradio     1692  227   979008 38340 sys_epoll_ 00000000 S com.redbend.vdmcu0_a9     1720  227   986664 50868 sys_epoll_ 00000000 S android.process.mediasystem    1736  227   977416 37228 sys_epoll_ 00000000 S com.android.keychainu0_a60    1764  227   977408 36920 sys_epoll_ 00000000 S com.android.smspushu0_a30    1779  227   1073396 88992 sys_epoll_ 00000000 S com.cyanogenmod.trebuchetu0_a52    1832  227   979260 39432 sys_epoll_ 00000000 S com.cyanogenmod.lockclocksystem    1854  227   986712 46544 sys_epoll_ 00000000 S org.cyanogenmod.cmpartsu0_a43    1883  227   995504 50448 sys_epoll_ 00000000 S com.android.calculator2u0_a16    1909  227   993656 42248 sys_epoll_ 00000000 S com.android.dialeru0_a41    1937  227   991976 41420 sys_epoll_ 00000000 S com.android.calendaru0_a5     1954  227   977320 37408 sys_epoll_ 00000000 S com.android.carrierconfigu0_a2     1971  227   987116 47844 sys_epoll_ 00000000 S android.process.acoreu0_a54    2009  227   993892 45456 sys_epoll_ 00000000 S com.android.emailu0_a4     2026  227   982520 40928 sys_epoll_ 00000000 S com.android.providers.calendaru0_a56    2760  227   977208 36528 sys_epoll_ 00000000 S com.qualcomm.timeserviceu0_a67    2803  227   1109540 86768 sys_epoll_ 00000000 S com.alibaba.android.rimet:channelshell     2951  212   3632   1312  sys_rt_sig b6e5839c S /system/bin/shshell     2978  2951  4576   1304           0 b6bff1e8 R ps

    其中,Zygote进程的PID为227,PPID为1;system_server进程的PID为806,PPID为227;

    Zygote启动之初进程名字叫app_process,Zygote启动之后Linux系统下的pctrl系统会调用app_process,将其名称换成zygote。

2 Zygote启动脚本

    init.rc脚本最前面就import了zygote相关的rc文件:

#对于Nexus5来说,${ro.zygote}的值为zygote32import /init.${ro.zygote}.rc

    在源码目录~/LineageOS/system/core/rootdir中有四个zygote相关的rc文件,分别是:

init.zygote32.rcinit.zygote64.rcinit.zygote32_64.rcinit.zygote64_32.rc

    Android5.0以后是支持64位程序的,Zygote也就有了32和64的差别,这里利用ro.zygote值得不同进而选择启动不同的Zygote进程。

2.1 init.zygote32.rc文件

    支持纯32位程序,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 audioserver    onrestart restart cameraserver    onrestart restart media    onrestart restart netd    writepid /dev/cpuset/foreground/tasks

    根据其中的onrestart可知,如果audioserver、cameraserver、media、netd等进程终止了,就需要重启。

2.2 init.zygote32_64.rc文件

    支持32位程序和64位程序,init.zygote32_64.rc文件内容为:

service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote    class main    socket zygote stream 660 root system    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    writepid /dev/cpuset/foreground/tasksservice zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary    class main    socket zygote_secondary stream 660 root system    onrestart restart zygote    writepid /dev/cpuset/foreground/tasks

    脚本中要启动Zygote进程,一个名称为zygote,执行程序为app_process32,作为主模式;另一个名为zygote_secondary,执行程序为app_process64,作为辅助模型。

    在我的上篇文章:中的第5节中介绍了Zygote进程是如何被init进程启动起来的。

3 Zygote进程启动过程分析

    先偷一张图来看看启动过程时序图:

        

    通过上面我们知道Zygote进程要执行的程序便是app_process了,它位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。

int main(int argc, char* const argv[]){    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {        // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return        // EINVAL. Don't die on such kernels.        if (errno != EINVAL) {            LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));            return 12;        }    }    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));    // 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.    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.    while (i < argc) {        const char* arg = argv[i++];        //Zygote进程是通过fork自身来创建创建子进程的,这样Zygote进程以及它的子进程都可以进入app_main.cpp的main函数,因此main函数为了区分当前运行在哪个进程,会判断arg中是否包含了参数“--zygote”,如果包含则说明main运行在Zygote进程中,将zygote设置为true;        if (strcmp(arg, "--zygote") == 0) {            zygote = true;            niceName = ZYGOTE_NICE_NAME;        //判断参数arg是否包含“--start-system-server”,如果包含则说明main运行在SystemServer进程中,并将startSystemServer设置为true        } 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
args; if (!className.isEmpty()) { // 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); } 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()); } //若zygote为true,说明当前运行在Zygote进程中,调用AppRuntime的start函数 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; }}

    AppRuntime的start方法在源码目录:~/LineageOS/frameworks/base/core/jni/AndroidRuntime.cpp

/* * 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
& 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; //启动Java虚拟机; if (startVm(&mJavaVM, &env, zygote) != 0) { return; } onVmCreated(env); /* * Register android functions. */ //为Java虚拟机注册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. */ 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); //从app_main的main函数得知className为com.android.internal.os.ZygoteInit; 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. */ //将className的.替换为“/”; char* slashClassName = toSlashClassName(className); //找到ZygoteInit jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { //找到ZygoteInit的main方法; 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 { //通过JNI调用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");}

    最终,Zygote进程成功通过JNI调用从Native层的app_process进入Java框架层的ZygotInit,真正进入了Java代码的世界!!

    打开源码目录:~/LineageOS/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,查看其main方法:

public static void main(String argv[]) {        // Mark zygote start. This ensures that thread creation will throw        // an error.        ZygoteHooks.startZygoteNoThreadCreation();        try {            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");            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.");           }            //创建一个Server端的Socket,socketname的值为“zygote”;            registerZygoteSocket(socketName);            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                SystemClock.uptimeMillis());            //预加载类和资源;            preload();            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                SystemClock.uptimeMillis());            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);            // Finish profiling the zygote initialization.            SamplingProfilerIntegration.writeZygoteSnapshot();            // Do an initial gc to clean up after startup            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");            gcAndFinalize();            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);            // Disable tracing so that forked processes do not inherit stale tracing tags from            // Zygote.            Trace.setTracingEnabled(false);            // Zygote process unmounts root storage spaces.            Zygote.nativeUnmountStorageOnInit();            ZygoteHooks.stopZygoteNoThreadCreation();            if (startSystemServer) {                //启动SystemServer进程                startSystemServer(abiList, socketName);            }            Log.i(TAG, "Accepting command socket connections");            //进入无限循环,在前面创建的Socket接口中等待ActivityManagerService请求,以创建新的应用程序进程;至于AMS如何与Zygote链接的等我分析AMS时再详细描述!            runSelectLoop(abiList);            closeServerSocket();        } catch (MethodAndArgsCaller caller) {            caller.run();        } catch (Throwable ex) {            Log.e(TAG, "Zygote died with exception", ex);            closeServerSocket();            throw ex;        }    }

    ZygoteInit的main方法主要完成4件事情:

  1. 创建一个Server端的Socket;
  2. 预加载类和资源;
  3. 启动SystemServer进程;
  4. 等待AMS请求创建新的应用程序进程;(标注一下:ActivityManagerService如何与Zygote链接的等我分析AMS时再详细描述!)

3.1 registerZygoteSocket方法

    进入源码目录:~/LineageOS/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,查看其registerZygoteSocket方法:

/**     * Registers a server socket for zygote command connections     *     * @throws RuntimeException when open fails     */    private static void registerZygoteSocket(String socketName) {        if (sServerSocket == null) {            int fileDesc;            //拼接Socket的名称,为"ANDROID_SOCKET_+zygote";            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;            try {                //得到Socket的环境变量的值,将fullSocketName转换为环境变量的值;                String env = System.getenv(fullSocketName);                //将Socket环境变量的值转换为文件描述符的参数;                fileDesc = Integer.parseInt(env);            } catch (RuntimeException ex) {                throw new RuntimeException(fullSocketName + " unset or invalid", ex);            }            try {                //创建文件描述符                FileDescriptor fd = new FileDescriptor();                //传入此前转换的文件操作符参数;                fd.setInt$(fileDesc);                //创建服务器端Socket,并将文件操作符作为参数传进去;Zygote进程将SystemServer进程启动后,就会在这个服务器端的Socket上等待AMS请求Zygote进程来创建新的应用程序进程;                sServerSocket = new LocalServerSocket(fd);            } catch (IOException ex) {                throw new RuntimeException(                        "Error binding to local socket '" + fileDesc + "'", ex);            }        }    }

    Zygote进程将SystemServer进程启动后,就会在这个服务器端的Socket上等待AMS请求Zygote进程来创建新的应用程序进程;

3.2 启动SystemServer进程

    进入源码目录:~/LineageOS/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,查看其startSystemServer方法:

/**     * 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_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        );        /* Containers run without this capability, so avoid setting it in that case */        if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {            capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);        }        /* Hardcoded command line to start the system server */        //创建args数组,用来保存启动SystemServer的启动参数;其中可看到SystemServer进程的用户id和用户组id被设置为1000,并且拥有用户组1001-1010、1018、1021、1032、3001-3010的权限;进程名为system_server,启动的类名为:com.android.server.SystemServer;        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,3009,3010",            "--capabilities=" + capabilities + "," + capabilities,            "--nice-name=system_server",            "--runtime-args",            "com.android.server.SystemServer",        };        ZygoteConnection.Arguments parsedArgs = null;        int pid;        try {            //将args数组封装成Arguments对象并提供给forkSystemServer使用;            parsedArgs = new ZygoteConnection.Arguments(args);            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);            /* Request to fork the system server process */            //调用ZygoteInit的forkSystemServer方法(native层调用的是nativeForkSystemServer方法,最终通过fork函数),创建一个子进程,也就是SystemServer进程;            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);            }            //处理SystemServer进程;            handleSystemServerProcess(parsedArgs);        }        return true;    }

   这样就去启动SystemServer进程了,SystemServer进程的启动过程后续博文再分析。

3.3 runSelectLoop方法

    进入源码目录:~/LineageOS/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,查看其runSelectLoop方法:

/**     * 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
fds = new ArrayList
(); ArrayList
peers = new ArrayList
(); //sServerSocket即在registerZygoteSocket方法中创建的服务器端Socket,调用sServerSocket.getFileDescriptor()函数来获得该Socket的fd字段的值并添加到fd列表fds中; fds.add(sServerSocket.getFileDescriptor()); peers.add(null); //无限循环等待AMS请求Zygote进程创建新的应用程序进程; while (true) { StructPollfd[] pollFds = new StructPollfd[fds.size()]; //通过遍历fds存储的信息转移到pollFds数组中; 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); } //对pollFds进行遍历,如果i==0说明服务器端Socket与客户端连接上了,也就是当前Zygote进程和AMS建立了连接; for (int i = pollFds.length - 1; i >= 0; --i) { if ((pollFds[i].revents & POLLIN) == 0) { continue; } if (i == 0) { //acceptCommandPeer方法得到ZygoteConnection类并添加到Socket连接列表peers中,然后将该ZygoteConnection的fd添加到fds中,以便可以接收到AMS发送过来的请求; ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { //调用ZygoteConnection的runOnce函数来创建一个新的应用程序进程,并在成功创建后将这个连接从Socket连接列表peers和fd列表fds中清除; boolean done = peers.get(i).runOnce(); if (done) { peers.remove(i); fds.remove(i); } } } } }

3.4 Zygote进程启动总结

Zygote进程启动共做了以下几波操作:

  1. 创建AppRuntime并调用其start方法,启动Zygote进程;
  2. 创建Java虚拟机并未Java虚拟机注册JNI方法;
  3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层;
  4. 通过registerZygoteSocket方法创建服务器端Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程;
  5. 启动SystemServer进程;

Enjoy it !!

   下一篇分析:

转载于:https://my.oschina.net/XiaoMaPedro/blog/3041699

你可能感兴趣的文章
闭包 !if(){}.call()
查看>>
python MySQLdb安装和使用
查看>>
Java小细节
查看>>
poj - 1860 Currency Exchange
查看>>
chgrp命令
查看>>
Java集合框架GS Collections具体解释
查看>>
洛谷 P2486 BZOJ 2243 [SDOI2011]染色
查看>>
linux 笔记本的温度提示
查看>>
数值积分中的辛普森方法及其误差估计
查看>>
Web service (一) 原理和项目开发实战
查看>>
跑带宽度多少合适_跑步机选购跑带要多宽,你的身体早就告诉你了
查看>>
广平县北方计算机第一届PS设计大赛
查看>>
深入理解Java的接口和抽象类
查看>>
java与xml
查看>>
Javascript异步数据的同步处理方法
查看>>
iis6 zencart1.39 伪静态规则
查看>>
SQL Server代理(3/12):代理警报和操作员
查看>>
基于事件驱动的DDD领域驱动设计框架分享(附源代码)
查看>>
Linux备份ifcfg-eth0文件导致的网络故障问题
查看>>
2018年尾总结——稳中成长
查看>>