使用的版本:Android 2.3
Zygote是Android系统应用中一个相当重要的进程,它的主要功能就是执行Android应用程序。在Android系统中运行新的应用,如同卵子受精分裂一样,需要跟Zygote进程结合后才能执行。
Zygote进程运行时,会初始化Dalvik虚拟机,并启动之。Android应用程序由java编写,不能直接已本地进程的形态运行在linux上,只能运行在Dalvik虚拟机中。每个应用程序都运行在各自的虚拟机中,应用程序每次运行都要重新初始化并启动虚拟机,这个过程会耗费相当长的时间,是拖慢应用程序的原因之一。因此,在Android中,应用程序运行前,Zygote进程通过共享已运行的虚拟机的代码与内存信息,缩短应用程序运行所耗费的时间,并且,它会事先将应用程序要使用的Android Framework中的类与资源加载到内存中,并组织形成所用资源的链接信息。新运行的Android应用程序在使用所需资源是不必每次重新形成资源的链接信息,这会节省大量时间,提高程序运行速度。
init进程启动之后,Android的服务与应用程序都由Zygote进程启动运行。Android设备中运行的进程大致有Daemon进程以及在Dalvik虚拟机中运行的Android应用程序两大类,pid为1的进程是init进程,ppid为1的进程是init进程启动的Daemon进程,其中包含Zygote进程。
Zygote启动后,初始并运行Dalvik虚拟机,然后将需要的类与资源加载到内存中。然后调用fork()创建出Zygote的子进程,子进程动态加载并运行Android应用程序,运行的应用程序会使用Zygote已经初始化并启动运行的Dalvik虚拟机代码,因为是fork()创建出的子进程,故使用已加载到内存中的类与资源可以使速度大大加快。
这里要考虑到COW(Copy on Write)技术,就是在创建新进程后,新进程会共享父进程的内存空间,使用COW技术,可以不用复制父进程的内存空间,而是直接共享父进程的内存空间,当需要修改内存空间的信息时,才将相关的内存信息复制到自身的内存空间。因为Zygote创建新进程的时候调用fork()直接运行exec(),新进程的内存空间与父进程的内存空间信息基本不同,复制父进程的内存空间做法变的毫无意义,并且会增加新进程运行的系统开销。
·app_process运行ZygoteInit class
Zygote由java编写而成,不能直接由init进程启动运行,故必须先生成Dalvik虚拟机,再在Dalvik虚拟机上装载运行ZygoteInit类。
这里给出frameworks/base/cmds/app_process/app_main.cpp中的main函数,即app_process进程的main函数。
int main(int argc, const char* const argv[])
{
// These are global variables in ProcessState.cpp
mArgC = argc;
mArgV = argv;
mArgLen = 0;
for (int i=0; i<argc; i++) {
mArgLen += strlen(argv[i]) + 1;
}
mArgLen--;
AppRuntime runtime;
const char *arg;
const char *argv0;
argv0 = argv[0];
// Process command line arguments
// ignore argv[0]
argc--;
argv++;
// Everything up to '--' or first non '-' arg goes to the vm
int i = runtime.addVmArguments(argc, argv);
// Next arg is parent directory
if (i < argc) {
runtime.mParentDir = argv[i++];
}
// Next arg is startup classname or "--zygote"
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0);
runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;
LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(), runtime.getClassName());
runtime.start();
}
} else {
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
return 10;
}
}
<span style="white-space:pre"></span>app_process进程会初始化一个AppRuntime对象,继承自AndroidRuntime类,AppRuntime对象会分析环境变量以及运行的参数,以此生成虚拟机选项。
<div>
</div>
<div>
<span style="font-size:14px"><span style="white-space:pre"></span>app_process服务运行时,init.rc文件中的运行命令如下:</span>
</div>
<div>
<span style="font-size:14px"><span style="white-space:pre"></span>/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server</span>
</div>
<div>
<span style="font-size:14px"><span style="white-space:pre"></span>传递给虚拟机的参数保存到AppRuntime类的对象中,然后加载对象,调用对象的main方法。</span>
</div>
<div>
<span style="font-size:14px"><span style="white-space:pre"></span></span>
<pre code_snippet_id="369733" snippet_file_name="blog_20140530_2_240974" name="code" class="cpp">if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0);
runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;
LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(), runtime.getClassName());
runtime.start();
}
} else {
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
return 10;
}
这是app_process main函数生成runtime对象的代码片段,Runtime对象的start()函数要获取与虚拟机运行相关的各种系统属性和环境变量,通过property_get()函数改变全局属性。Runtime对象的start()函数通过调用JNI_CreateJavaVM()函数来创建并运行虚拟机。
下面给出AndroidRuntime.cpp的start()函数,在frameworks/base/core/jni目录中
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
className != NULL ? className : "(unknown)");
char* slashClassName = NULL;
char* cp;
JNIEnv* env;
blockSigpipe();
/*
* 'startSystemServer == true' means runtime is obslete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
if (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.");
goto bail;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
/* start the virtual machine */
if (startVm(&mJavaVM, &env) != 0)
goto bail;
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
/*
* We want to call main() with a String array with arguments in it.
* At present we only have one argument, the class name. Create an
* array to hold it.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
jstring startSystemServerStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(2, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
startSystemServerStr = env->NewStringUTF(startSystemServer ?
"true" : "false");
env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
jclass startClass;
jmethodID startMeth;
slashClassName = strdup(className);
for (cp = slashClassName; *cp != '\0'; cp++)
if (*cp == '.')
*cp = '/';
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
LOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
LOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
LOGW("Warning: VM did not shut down cleanly\n");
bail:
free(slashClassName);
}
创建完VM之后,app_process会加载Zygote相关的类,其中上述的start()函数中,会加载ZygoteInit类
for (cp = slashClassName; *cp != '\0'; cp++)
if (*cp == '.')
*cp = '/';
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
这是AndroidRuntime类start()函数加载ZygoteInit类的代码。
·ZygoteInit的功能
1.绑定套接字,接收新Android应用程序运行请求
2.加载Android Application Framework使用的类与资源
3.启动运行System Server
4.处理新Android应用程序运行请求
ZygoteInit类的源代码在frameworks\base\core\java\com\android\internal\os目录下的ZygoteInit.java文件中
下面是main方法:
public static void main(String argv[]) {
try {
VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
<span style="background-color: rgb(255, 255, 255);"> <span style="color:#ffff33;"> </span><span style="color:#000099;">registerZygoteSocket();</span></span>
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
<span style="color:#3366ff;"> <span style="background-color: rgb(255, 255, 255);">preloadClasses();
//cacheRegisterMaps();
preloadResources();</span></span>
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
gc();
// If requested, start system server directly from Zygote
if (argv.length != 2) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
if (argv[1].equals("true")) {
<span style="color:#000099;"> <span style="background-color: rgb(255, 255, 255);">startSystemServer();</span></span>
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
<span style="background-color: rgb(255, 255, 255);"><span style="color:#33ccff;"> runSelectLoopMode();</span></span>
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
这四个方法分别:
1.绑定套接字UDS(Unix Domain Socket)
2.预加载类、平台资源(图像、XML类、信息、字符串等)
3.参数--start-system-server会调用startSystemServer()方法启动系统服务器,系统服务器用来运行一些主要的本地服务
4.监视UDS,收到新的Android应用程序生成请求,则进入处理循环
1.绑定/dev/socket/zygote套接字
Zygote生成的UDS套接字,从ActivityManager接收新Android应用程序的生成请求。init.rc文件中有生成该套接字的相关内容
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
ZygoteInit的main方法会先调用registerZygoteSocket()方法,代码如下
private static void registerZygoteSocket() {
if (sServerSocket == null) {
int fileDesc;
try {
String env = System.getenv(ANDROID_SOCKET_ENV);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(
ANDROID_SOCKET_ENV + " unset or invalid", ex);
}
try {
sServerSocket = new LocalServerSocket(
createFileDescriptor(fileDesc));
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
registerZygoteSocket()方法会创建一个LocalServerSocket类的对象,并将其与/dev/socket/zygote绑定在一起,接收生成新Android进程的信息,并在最后的循环语句中进行处理。
2.加载应用程序Framework中的类与平台资源
preloadClasses()方法的主要代码如下:
private static void preloadClasses() {
final VMRuntime runtime = VMRuntime.getRuntime();
InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(
PRELOADED_CLASSES);
if (is == null) {
Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
} else {
Log.i(TAG, "Preloading classes...");
long startTime = SystemClock.uptimeMillis();
// Drop root perms while running static initializers.
setEffectiveGroup(UNPRIVILEGED_GID);
setEffectiveUser(UNPRIVILEGED_UID);
// Alter the target heap utilization. With explicit GCs this
// is not likely to have any effect.
float defaultUtilization = runtime.getTargetHeapUtilization();
runtime.setTargetHeapUtilization(0.8f);
// Start with a clean slate.
runtime.gcSoftReferences();
runtime.runFinalizationSync();
Debug.startAllocCounting();
try {
BufferedReader br
= new BufferedReader(new InputStreamReader(is), 256);
int count = 0;
String line;
while ((line = br.readLine()) != null) {
// Skip comments and blank lines.
line = line.trim();
if (line.startsWith("#") || line.equals("")) {
continue;
}
try {
if (Config.LOGV) {
Log.v(TAG, "Preloading " + line + "...");
}
Class.forName(line);
if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
if (Config.LOGV) {
Log.v(TAG,
" GC at " + Debug.getGlobalAllocSize());
}
runtime.gcSoftReferences();
runtime.runFinalizationSync();
Debug.resetGlobalAllocSize();
}
count++;
} catch (ClassNotFoundException e) {
Log.w(TAG, "Class not found for preloading: " + line);
} catch (Throwable t) {
Log.e(TAG, "Error preloading " + line + ".", t);
if (t instanceof Error) {
throw (Error) t;
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new RuntimeException(t);
}
}
Log.i(TAG, "...preloaded " + count + " classes in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
// Restore default.
runtime.setTargetHeapUtilization(defaultUtilization);
Debug.stopAllocCounting();
// Bring back root. We'll need it later.
setEffectiveUser(ROOT_UID);
setEffectiveGroup(ROOT_GID);
}
}
}
代码主要通过获取一个输入流,以便获取preloaded-classes文件中记录的类,创建BufferedReader对象,并读取preloaded-classes文件的内容,调用Class.forName()方法,将读到的类动态的加载到内存中。
3.运行SystemServer
Zygote启动Dalvik虚拟机后,会再生成一个Dalvik虚拟机实例,以便运行名称为SystemServer的Java服务,SystemServer用于运行Audio Flinger与Surface Flinger本地服务。在运行完所需的本地服务之后,SystemServer开始运行Android Framework的服务,如ActivityManager、PackageManager等。
下面是startSystemServer()方法:
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* 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,3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
/*
* Enable debugging of the system process if *either* the command line flags
* indicate it should be debuggable or the ro.debuggable system property
* is set to "1"
*/
int debugFlags = parsedArgs.debugFlags;
if ("1".equals(SystemProperties.get("ro.debuggable")))
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
代码定义了一个字符串数组,保存SystemServer的启动参数,这些参数被硬编码进字符串数组,字符串数组中的最后一个参数用于指定SystemServer类。接着调用forkSystemServer()方法来创建新进程,并运行SystemServer,同时检查生成的SystemServer进程工作是否正常。SystemServer类的main()方法会加载名称为android_servers的本地库,然后继续调用init1()函数,init1()函数调用system_init()函数,启动Audio Flinger、Surface Flinger、MediaPlayerService、CameraService等本地服务。
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
// Start the sensor service
SensorService::instantiate();
// On the simulator, audioflinger et al don't get started the
// same way as on the device, and we need to start them here
if (!proc->supportsProcesses()) {
// Start the AudioFlinger
AudioFlinger::instantiate();
// Start the media playback service
MediaPlayerService::instantiate();
// Start the camera service
CameraService::instantiate();
// Start the audio policy service
AudioPolicyService::instantiate();
}
// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
LOGI("System server: starting Android services.\n");
runtime->callStatic("com/android/server/SystemServer", "init2");
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}
本地服务注册完毕后调用SystemServer类的静态方法init2(),创建android.server.ServerThread线程,并启动它,从而运行Android Framework的主要服务。
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
4.运行新的Android应用程序
看一下ZygoteInit类的runSelectLoopMode()方法,frameworkds/base/core/java/com/android/internal/os
private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList();
ArrayList<ZygoteConnection> peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4];
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
/*
* Call gc() before we block in select().
* It's work that has to be done anyway, and it's better
* to avoid making every child do it. It will also
* madvise() any free memory as a side-effect.
*
* Don't call it every time, because walking the entire
* heap is a lot of overhead to free a few hundred bytes.
*/
if (loopCount <= 0) {
gc();
loopCount = GC_LOOP_COUNT;
} else {
loopCount--;
}
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
}
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
该方法采用典型的异步处理方式。代码首先将套接字的描述符添加到描述符数组中,程序使用该描述符处理来自外部的连接请求。selectReadable()是一个jni本地方法的本地函数,用来监视参数传递过来的文件描述符数组,若描述符目录中存在相关事件,则返回其在数组中的索引。为了处理dev/socket/zygote套接字的连接请求,程序先创建出ZygoteConnection类的对象,检查请求连接一方的访问权限,处理ZygoteConnection对象的输入输出事件。被添加的套接字面束缚的输入输出事件在下一个循环中由selectReadable()方法检测。runOnce()方法用于处理新连接的输入输出套接字,并生成新的Android应用程序。
下面是runOnce()方法:
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
Log.w(TAG, "IOException on command socket " + ex.getMessage());
closeSocket();
return true;
}
if (args == null) {
// EOF reached.
closeSocket();
return true;
}
/** the stderr of the most recent request, if avail */
PrintStream newStderr = null;
if (descriptors != null && descriptors.length >= 3) {
newStderr = new PrintStream(
new FileOutputStream(descriptors[2]));
}
int pid;
try {
parsedArgs = new Arguments(args);
applyUidSecurityPolicy(parsedArgs, peer);
applyDebuggerSecurityPolicy(parsedArgs);
applyRlimitSecurityPolicy(parsedArgs, peer);
applyCapabilitiesSecurityPolicy(parsedArgs, peer);
int[][] rlimits = null;
if (parsedArgs.rlimits != null) {
rlimits = parsedArgs.rlimits.toArray(intArray2d);
}
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, parsedArgs.debugFlags, rlimits);
} catch (IllegalArgumentException ex) {
logAndPrintError (newStderr, "Invalid zygote arguments", ex);
pid = -1;
} catch (ZygoteSecurityException ex) {
logAndPrintError(newStderr,
"Zygote security policy prevents request: ", ex);
pid = -1;
}
if (pid == 0) {
// in child
handleChildProc(parsedArgs, descriptors, newStderr);
// should never happen
return true;
} else { /* pid != 0 */
// in parent...pid of < 0 means failure
return handleParentProc(pid, descriptors, parsedArgs);
}
}
这个方法读取请求信息,包含新创建进程的参数选项,分析请求信息中的字符串数组,为运行进程设置好各个选项,创建新进程,Zygote.forkAndSpecialize()方法接收上面分析好的参数,调用Zygote类的本地方法forkAndSpecialize(),然后调用本地方法fork(),创建新进程,并根据新创建的进程传递的选项,设置uid,gid,rlimit等。handleChildProc()函数用来加载新进程所需的类,并调用类的main()方法,Zygote返回新进程创建是否成功,若成功,则返回进程的pid,最后,请求完成后,断开连接,关闭套接字。
最后,从套接字描述符数组中删除套接字描述符,防止重复处理。Zygote重新返回到循环中,等待并处理新请求。