Android Zygote解析

来源:互联网 发布:廖雪峰python视频下载 编辑:程序博客网 时间:2024/06/06 17:17

使用的版本: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重新返回到循环中,等待并处理新请求。
0 0
原创粉丝点击