Zygote 的启动流程

在Android中,Java虚拟机、应用程序进程、系统服务进程都是由Zygote进程fork出来的,下面我们就来分析下Zygote的启动过程。

一、init创建zygote

众所周知,android是基于linux内核的,而linux中所有进程又都是init进程(pid为0)的子孙进程,那zygote进程自然也得由init进程来fork了。从init.rc文件我们能看到,它会先根据平台导入对应的zygote相关rc文件,然后在late-init阶段触发zygote-start(即启动zygote服务)。另外如果该设备支持Encryption(如FDE/FBE等),则需在decrypt状态下再触发zygote-start,关于其原因这里不再赘述,请查阅加密相关博文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#system/core/rootdir/init.rc
# ro.zygote表示支持32/64位
import /init.${ro.zygote}.rc
on late-init
#若有打开FBE功能,则在此处启动zygote
trigger zygote-start
...
# 建议将不必要的/data初始化从post-fs-data挪到start-zygote,以避免阻塞zygote
# 处于未加密状态
on zygote-start && property:ro.crypto.state=unencrypted
start zygote
start zygote_secondary
# 不支持加密
on zygote-start && property:ro.crypto.state=unsupported
start zygote
start zygote_secondary
# 文件级加密且处于加密状态
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
start zygote
start zygote_secondary
...
on property:vold.decrypt=trigger_post_fs_data
# 解密状态下在此处启动zygote
trigger zygote-start

刚才我们提到init.rc文件中会根据平台的差异来加载对应的zygote相关的rc文件,主要分为zygote32、zygote64、zygote32_64、zygote64_32四种,它们的区别就在于是执行app_process还是app_process64程序。鉴于当前智能机大多是64位系统,下面就附上init.zygote64.rc来简单看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#system/core/rootdir/init.zygote64.rc
#进程类型:service
#进程名称:zygote
#可执行程序:/system/bin/app_process64
#启动参数:-Xzygote /system/bin --zygote --start-system-server
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
#创建一个socket:/dev/socket/zygote
#zygote会监听该socket,应用程序进程启动即会fork一个对应的进程
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
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks

二、app_main的main函数

从Android.mk/Android.bp中很容易知晓:app_process/app_process64对应的源代码即是app_main.cpp。下面先来看看它的main函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
if (!LOG_NDEBUG) {
String8 argv_String;
for (int i = 0; i < argc; ++i) {
argv_String.append("\"");
argv_String.append(argv[i]);
argv_String.append("\" ");
}
ALOGV("app_process main with argv: %s", argv_String.string());
}
// -Xzygote /system/bin --zygote --start-system-server
// AppRuntime是AndroidRuntime的子类,此处创建Android运行时环境
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// 处理命令行参数,忽略argv[0]
argc--;
argv++;
// --zygote : 表示从zygote模式开始;
// --start-system-server : 表示启动system server;
// --application : 表示从应用模式开始(独立,非zygote);
// --nice-name : 表示该过程的名字;
// 对于非zygote启动,这些参数后面将跟着主要类名。所有剩余的参数都传递给此类的main方法。
// 对于zygote启动,所有剩余的参数都传递给zygote的main方法。
// 需要注意的是我们必须复制参数字符串值,因为当我们将nice-name应用于argv0时,我们将重写整个参数块。
const char* spaced_commands[] = { "-cp", "-classpath" };
bool known_command = false;
int i;
for (i = 0; i < argc; i++) {
if (known_command == true) {
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add known option '%s'", argv[i]);
known_command = false;
continue;
}
for (int j = 0;
j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
++j) {
if (strcmp(argv[i], spaced_commands[j]) == 0) {
known_command = true;
ALOGV("app_process main found known command '%s'", argv[i]);
}
}
if (argv[i][0] != '-') {
break;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
// 保存-Xzygote参数
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add option '%s'", argv[i]);
}

// 解析运行时参数。
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i;
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
// 32位是zygote,64位是zygote64
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()) {
// 运行application或tool
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
if (!LOG_NDEBUG) {
String8 restOfArgs;
char* const* argv_new = argv + i;
int argc_new = argc - i;
for (int k = 0; k < argc_new; ++k) {
restOfArgs.append("\"");
restOfArgs.append(argv_new[k]);
restOfArgs.append("\" ");
}
ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
}
} else {
// 当前处于zygote模式,创建/data/dalvik-cache路径
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
// 32位是ro.product.cpu.abilist32,64位是ro.product.cpu.abilist64
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);
// 在zygote模式,将所有剩余参数传递给zygote的main函数
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
// 设置进程名
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) {
// 启动ZygoteInit
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.");
}
}

三、AndroidRuntime的start函数

AndroidRuntime的start函数主要做了3件事:
(1)调用startVM方法,用于启动虚拟机;
(2)调用startReg方法,用于注册JNI方法;
(3)调用ZygoteInit的main方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// frameworks/base/core/jni/AndroidRuntime.cpp
// 启动Android runtime。这涉及启动虚拟机并在“className”命名的类中调用“static void main(String [] args)”方法。
// 传递main函数的两个参数,类名和指定的选项字符串。
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'表示runtime已过时,不再从init.rc运行,因此我们在此处打印出启动启动事件。
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");
// 如果环境变量中没有ANDROID_ROOT,则新增该变量,并设置值为'/system'
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);
}
// 启动虚拟机
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
// 注册JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
// 我们想用一个带有参数的String数组调用main方法。目前我们有两个参数,类名和选项字符串。创建一个数组来保存它们。
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);
}
// 启动VM。该线程成为VM的主线程,并且在VM退出之前不会返回。
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
ALOGD("Shutting down VM\n");
// Zygote退出。
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");
}

四、ZygoteInit的main方法

通过JNI调用ZygoteInit的main方法,开始进入zygote的Java世界。它主要做了4件事情:
(1)调用registerZygoteSocket方法来创建socket接口,用于同ActivityManagerService进行通讯;
(2)调用preload方法来预加载一些类、资源及库,用于提升应用启动速度;
(3)调用forkSystemServer方法,用于启动SystemServer;
(4)调用runSelectLoopMode方法,用于无限循环在socket接口上,等待AMS请求来创建新的应用程序进程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
// 创建zygoteServer对象
ZygoteServer zygoteServer = new ZygoteServer();
// 标记zygote启动。确保创建线程能抛出错误。
ZygoteHooks.startZygoteNoThreadCreation();
// zygote进入自己的进程组
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
final Runnable caller;
try {
// 将Zygote的开始时间报告为tron,除非它是runtime重启
if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
MetricsLogger.histogram(null, "boot_zygote_init",
(int) SystemClock.elapsedRealtime());
}
String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
bootTimingsTraceLog.traceBegin("ZygoteInit");
// 开启DDMS功能
RuntimeInit.enableDdms();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
// 注册Zygote用的socket,用于和AMS交互
zygoteServer.registerServerSocketFromEnv(socketName);
// 在某些配置中,我们避免急于预加载资源和类。
// 在这种情况下,我们会在第一次fork之前预先加载东西。
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
// 在启动后进行初始GC清理
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit
// 禁用跟踪,以便fork的进程不从Zygote继承过时的跟踪标记。
Trace.setTracingEnabled(false, 0);
Zygote.nativeSecurityInit();
// Zygote进程卸载根存储空间。
Zygote.nativeUnmountStorageOnInit();
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null}在父(zygote)进程中,{@code r != null}在子(system_server)进程中。
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// select循环在fork进程的早期返回,并且在zygote中永远循环。
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
// 关闭socket
zygoteServer.closeServerSocket();
}
// 我们正处于子进程中并退出了选择循环。继续执行命令。
if (caller != null) {
caller.run();
}
}

4.1 ZygoteInit的registerServerSocketFromEnv方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
// 注册一个socket服务器用于zygote命令连接。它通过一个ANDROID_SOCKET_环境变量定位socket服务器文件描述符。当打开失败时抛出RuntimeException。
void registerServerSocketFromEnv(String socketName) {
if (mServerSocket == 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);
mServerSocket = new LocalServerSocket(fd);
mCloseSocketFd = true;
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}

4.2 ZygoteInit的preload方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
beginPreload();
// 预加载/system/etc/preloaded-classes中的类
preloadClasses();
// 预加载缓存中无需启动的类
cacheNonBootClasspathClassLoaders();
// 预加载资源,如drawable、color资源等
preloadResources();
// 预加载应用进程hal层东东
nativePreloadAppProcessHALs();
// 预加载OpenGL
preloadOpenGL();
// 预加载共享库,如android、compiler_rt、jnigraphics
preloadSharedLibraries();
// 预加载文本字体等资源
preloadTextResources();
// 仅运行于zygote进程中,用于内存共享
WebViewFactory.prepareWebViewInZygote();
endPreload();
// 注册AndroidKeyStoreProvider,并warm up已注册的providers。
warmUpJcaProviders();
Log.d(TAG, "end preload");
sPreloadComplete = true;
}

4.3 ZygoteInit的forkSystemServer方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
// 准备参数和forks用于system server进程。返回{@code Runnable},它提供子进程中system_server代码的入口点,以及父进程中的{@code null}。
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM,
OsConstants.CAP_BLOCK_SUSPEND
);
// 容器在没有某些功能的情况下运行,因此请删除任何不可用的大写字母
StructCapUserHeader header = new StructCapUserHeader(
OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
StructCapUserData[] data;
try {
data = Os.capget(header);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to capget()", ex);
}
capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
// 用于启动系统服务器的硬编码命令行
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
// 请求fork系统服务器进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
// 子进程
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}

4.4 ZygoteInit的runSelectLoop方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
// 运行zygote进程的select循环。接收时会接受新连接,并且一次从一个spawn-request的连接中读取命令。
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
// sServerSocket是socket通信中的服务端,即zygote进程。保存到fds[0]
fds.add(mServerSocket.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 {
// 处理轮询状态,当pollFds有事件到来则往下执行,否则阻塞在这里
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
// 采用I/O多路复用机制,当接收到客户端发出连接请求或者数据处理请求到来,则往下执行;
// 否则进入continue,跳出本次循环。
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
// 即fds[0],代表的是sServerSocket,则意味着有客户端连接请求;
// 则创建ZygoteConnection对象,并添加到fds。
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
// i>0,则代表通过socket接收来自对端的数据,并执行相应操作
try {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
// 在子进程 - 如果processOneCommand没有调用“exec”,我们应该总是有一个命令在这个阶段运行。
if (command == null) {
throw new IllegalStateException("command == null");
}

return command;
} else {
// 我们在服务器中 - 我们永远不应该运行任何命令。
if (command != null) {
throw new IllegalStateException("command != null");
}
// 我们不知道socket的远程端是否已关闭,直到我们尝试从processOneCommand读取它。 这在我们的常规处理循环中显示为常规POLLIN事件。
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
if (!mIsForkChild) {
// 我们在服务器中,所以这里的任何异常都是在处理命令或从控制socket读取/写入时发生的。
// 对任何此类异常发出巨大的声音,以便我们确切地知道失败的原因。
Slog.e(TAG, "Exception executing zygote command: ", e);
// 确保socket已关闭,以便另一端立即知道出现了问题,并且没有超时等待响应。
ZygoteConnection conn = peers.remove(i);
conn.closeSocket();

fds.remove(i);
} else {
// 在子进程,所以在这里发现的任何异常都发生在fork之后和我们执行ActivityThread.main(或任何其他main方法之前)。
// 记录异常的详细信息并关闭该过程。
Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e;
}
} finally {
// 如果子进程是子对象,则重置子标志。 返回Runnable后,不会查询此循环传递的标志。
mIsForkChild = false;
}
}
}
}
}