声明
- 前阶段在项目中涉及到了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系统中主要有三个重要的进程系统:
- Zygote进程:被称为孵化进程,功能和Linux中的fork类似,不同的是它在Android系统中用来产生Java层的子进程;
- System进程:系统进程,是Android Framework所在的进程,用于启动Android系统。核心进程为Zygote进程fork出来的system_server,由system_server再去启动Framework层各个系统服务;
- 应用程序进程:每个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; } } Vectorargs; 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件事情:
- 创建一个Server端的Socket;
- 预加载类和资源;
- 启动SystemServer进程;
- 等待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 { ArrayListfds = 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进程启动共做了以下几波操作:
- 创建AppRuntime并调用其start方法,启动Zygote进程;
- 创建Java虚拟机并未Java虚拟机注册JNI方法;
- 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层;
- 通过registerZygoteSocket方法创建服务器端Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程;
- 启动SystemServer进程;
Enjoy it !!
下一篇分析: