Android 5.1 Lollipop的Zygote分析——下篇

来源:互联网 发布:1-10伪随机数生成算法 编辑:程序博客网 时间:2024/05/20 06:10

上一篇结尾的时候,说过AppRuntime的start()最后会加载Java层次的ZygoteInit类(com.android.internal.os.ZygoteInit),并调用其main函数。

ZygoteInit要做一些和Android平台紧密相关的重要动作,比如创建LocalServerSocket对象、预加载一些类以及资源、启动“Android系统服务”.

ZygoteInit类源码位置:Android源码/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

12345678910111213141516171819202122232425262728293031
public static void main(String argv[]) {    try {        // Start profiling the zygote initialization.        SamplingProfilerIntegration.start();        boolean startSystemServer = false;        String socketName = "zygote";//-----------------------------------        .................................................        registerZygoteSocket(socketName);//-----------------------注册zygote套接字        EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,            SystemClock.uptimeMillis());        preload();//------------------------------------------------预加载资源        EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,            SystemClock.uptimeMillis());        .................................................        if (startSystemServer) {//-------------------------------- 启动 system server 服务            startSystemServer(abiList, socketName);        }        Log.i(TAG, "Accepting command socket connections");        runSelectLoop(abiList);//------------------------------------        closeServerSocket();    } catch (MethodAndArgsCaller caller) {        caller.run();    } catch (RuntimeException ex) {        Log.e(TAG, "Zygote died with exception", ex);        closeServerSocket();        throw ex;    }}

registerZygoteSocket

其中registerZygoteSocket函数代码如下图所示

代码中 ANDROID_SOCKET_PREFIX 定义如下:

1
private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";

那么fullSocketName就是ANDROID_SOCKET_zygote了。要想知道这个环境变量,是怎么来的,那就要先分析init进程了,这不是我们的重点,等后面分析init进程的时候,在详细讨论这个变量的由来。

这里先简单说一下吧。在前面提到的关于zygote的rc配置文件,例如init.zygote32.rc中,有这么个option内容:

1
socket zygote stream 660 root system

说明zygote进程需要一个名为“zygote”的“流型(stream)”socket,当init进程真的启动zygote服务时,会走到service_start(),该函数会检查到zygote服务,需要一个“流型(stream)”的socket,那么便会在/dev/socket中为其创建一个名为zygote的流类型socket,并把新建的socket的文件描述符记录在以“ANDROID_SOCKET_zygote”的环境变量中。

那么ZygoteInit类中main函数下面的代码就清楚了其含义了:

12
String env = System.getenv(ANDROID_SOCKET_ENV);fileDesc = Integer.parseInt(env);

从环境变量的字符串中解析出文件描述符,然后创建LocalServerSocket对象,并将其记录在静态变量sServerSocket中,以后zygote进程会循环监听这个socket,一旦accept到连接请求,就创建命令连接(Command Connection)。监听动作的细节是在runSelectLoop()中。

预先加载类和资源

预先加载类

注册完socket接口,ZygoteInit会预加载一些类,这些类记录在Android源码/frameworks/base/preloaded-classes文本文件里:

12345678910111213
# Classes which are preloaded by com.android.internal.os.ZygoteInit.# Automatically generated by frameworks/base/tools/preload/WritePreloadedClassFile.java.# MIN_LOAD_TIME_MICROS=1250# MIN_PROCESSES=10........................................[Landroid.accounts.Account;[Landroid.animation.Animator;[Landroid.animation.Keyframe$FloatKeyframe;[Landroid.animation.Keyframe$IntKeyframe;[Landroid.animation.PropertyValuesHolder;[Landroid.app.FragmentState;[Landroid.app.LoaderManagerImpl;........................................

这个文件开头已经说的很清楚了,预先加载的这些类,每个加载时间都至少是1250微秒。Android 5.1中预先加载的类大约有3000个,可想而已Android启动的时候,花在这上面的时间可不少呢。preload函数中会调研preloadClasses()的函数预先加载这些类。

预先加载资源

preload函数中还会利用preloadResources()函数预先加载一些资源,这些资源记录在Android源码/frameworks/base/core/res/res/values/arrays.xml中。

基本上有两大类资源:
1)一类和图片有关(preloaed_drawables)
2)另一类和颜色有关(preloaded_color_state_lists)

预先加载的其他资源

preload函数还要调用下面两个函数还要预先加载opengl和一些so库。

123456789101112
private static void preloadSharedLibraries() {    Log.i(TAG, "Preloading shared libraries...");    System.loadLibrary("android");    System.loadLibrary("compiler_rt");    System.loadLibrary("jnigraphics");}private static void preloadOpenGL() {    if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) {        EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);    }}

启动system server服务

ZygoteInit的main()函数会调用startSystemServer()来启动system server,这是Android上层系统最重要的服务了。其大体做法是先fork一个子进程,然后在子进程中做一些初始化动作,继而执行SystemServer类的main()静态函数。需要注意的是,startSystemServer()并不是在函数体内直接调用Java类的main()函数的,而是通过抛异常的方式,在startSystemServer()之外加以处理的。

startSystemServer函数部分代码如下:

123456789101112131415161718192021222324252627282930313233343536373839404142
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,1018,1021,1032,                        3001,3002,3003,3006,3007",        "--capabilities=" + capabilities + "," + capabilities,        "--runtime-init",        "--nice-name=system_server",        "com.android.server.SystemServer",    };    ZygoteConnection.Arguments parsedArgs = null;    int pid;    try {        parsedArgs = new ZygoteConnection.Arguments(args);        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);         // fork出系统服务对应的进程        pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,                                            parsedArgs.gids, parsedArgs.debugFlags, null,                                            parsedArgs.permittedCapabilities,                                            parsedArgs.effectiveCapabilities);    } catch (IllegalArgumentException ex) {        throw new RuntimeException(ex);    }     // 对新fork出的系统进程,执行handleSystemServerProcess()    if (pid == 0) {            if (hasSecondZygote(abiList)) {                waitForSecondaryZygote(socketName);            }            handleSystemServerProcess(parsedArgs);        }    return true;}

Zygote.forkSystemServer

android源码/frameworks/base/core/java/com/android/internal/os/Zygote.java

12345678
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {    VM_HOOKS.preFork();    int pid = nativeForkSystemServer(            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);    VM_HOOKS.postForkCommon();    return pid;}

其中参数可以从下面获取:

12345678910
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",    "--capabilities=" + capabilities + "," + capabilities,    "--runtime-init",    "--nice-name=system_server",    "com.android.server.SystemServer",};

nativeForkSystemServer()是个native成员函数,其对应的C++层代码位置:Android源码/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp :

123456789101112131415161718192021222324
static jint com_android_internal_os_Zygote_nativeForkSystemServer(        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,        jlong effectiveCapabilities) {  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,                                      debug_flags, rlimits,                                      permittedCapabilities, effectiveCapabilities,                                      MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,                                      NULL, NULL);  if (pid > 0) {      // The zygote process checks whether the child process has died or not.      ALOGI("System server process %d has been created", pid);      gSystemServerPid = pid;      // There is a slight window that the system server process has crashed      // but it went unnoticed because we haven't published its pid yet. So      // we recheck here just to make sure that all is well.      int status;      if (waitpid(pid, &status, WNOHANG) == pid) {          ALOGE("System server process %d has died. Restarting Zygote!", pid);          RuntimeAbort(env);      }  }  return pid;}

forkAndSpecializeCommon()内部其实会调用fork(),而后设置gid、uid等信息

handleSystemServerProcess

startSystemServer()会在新fork出的子进程中调用handleSystemServerProgress(),让这个新进程成为真正的系统进程(SystemServer进程)

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
/**    * Finish remaining work for the newly forked system server process.    */   private static void handleSystemServerProcess(           ZygoteConnection.Arguments parsedArgs)           throws ZygoteInit.MethodAndArgsCaller {       closeServerSocket();//------------------因为子进程是system server 不是zygote,所以要关闭zygote socket       // set umask to 0077 so new files and directories will default to owner-only permissions.       Os.umask(S_IRWXG | S_IRWXO);       if (parsedArgs.niceName != null) {           Process.setArgV0(parsedArgs.niceName);//----------------niceName 是 system_server       }       final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");       if (systemServerClasspath != null) {           performSystemServerDexOpt(systemServerClasspath);       }       if (parsedArgs.invokeWith != null) {           String[] args = parsedArgs.remainingArgs;           // If we have a non-null system server class path, we'll have to duplicate the           // existing arguments and append the classpath to it. ART will handle the classpath           // correctly when we exec a new process.           if (systemServerClasspath != null) {               String[] amendedArgs = new String[args.length + 2];               amendedArgs[0] = "-cp";               amendedArgs[1] = systemServerClasspath;               System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);           }           WrapperInit.execApplication(parsedArgs.invokeWith,                   parsedArgs.niceName, parsedArgs.targetSdkVersion,                   null, args);       } else {           ClassLoader cl = null;           if (systemServerClasspath != null) {               cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());               Thread.currentThread().setContextClassLoader(cl);           }           /*            * Pass the remaining arguments to SystemServer.            */           // 此时的remainingArgs就是”com.android.server.SystemServer”           RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);       }       /* should never reach here */   }

因为当前已经不是运行在zygote进程里了,所以zygote里的那个监听socket就应该关闭了.在handleSystemServerProcess()函数里,parsedArgs.niceName就是“system_server”,而且因为parsedArgs.invokeWith没有指定,所以其值为null,于是程序会走到RuntimeInit.zygoteInit().

Android源码/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

1234567891011
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)           throws ZygoteInit.MethodAndArgsCaller {       if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");       redirectLogStreams();//-------------在新fork出的系统进程里,需要重新定向系统输出流       commonInit();       nativeZygoteInit();       applicationInit(targetSdkVersion, argv, classLoader);   }

上面调用的nativeZygoteInit()是个JNI函数,在AndroidRuntime.cpp文件中可以看到:

12345678910111213141516
/* * JNI registration. */static JNINativeMethod gMethods[] = {    { "nativeFinishInit", "()V",        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },    { "nativeZygoteInit", "()V",        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },    { "nativeSetExitWithoutCleanup", "(Z)V",        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },};static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz){    gCurRuntime->onZygoteInit();}

gCurRuntime是C++层的AndroidRuntime类的静态变量。在AndroidRuntime构造之时,gCurRuntime = this

其中onZygoteInit是一个虚函数,是有AndroidRuntime的子类AppRuntime负责实现的。

Android源码/framework/base/cmds/app_process/App_main.cpp

123456789
virtual void onZygoteInit()  {      // Re-enable tracing now that we're no longer in Zygote.      atrace_set_tracing_enabled(true);      sp<ProcessState> proc = ProcessState::self();      ALOGV("App process: starting thread pool.\n");      proc->startThreadPool();  }

里面构造了进程的ProcessState全局对象,而且启动了线程池。 这就涉及到了Binder机制的知识了,关于Binder后面再讲。

也就是说system server进程内部会开启一个线程池。

在来看applicationInit()函数的代码如下:

123456789101112131415161718
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)        throws ZygoteInit.MethodAndArgsCaller {    nativeSetExitWithoutCleanup(true);    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);    final Arguments args;    try {        args = new Arguments(argv);    } catch (IllegalArgumentException ex) {        Slog.e(TAG, ex.getMessage());        // let the process exit        return;    }    // Remaining arguments are passed to the start class's static main  invokeStaticMain(args.startClass, args.startArgs, classLoader);
1234567891011121314151617181920212223242526272829303132333435
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)         throws ZygoteInit.MethodAndArgsCaller {     Class<?> cl;     try {         cl = Class.forName(className, true, classLoader);     } catch (ClassNotFoundException ex) {         throw new RuntimeException(                 "Missing class when invoking static main " + className,                 ex);     }     Method m;     try {         m = cl.getMethod("main", new Class[] { String[].class });//-----------------注意看这里的 main     } catch (NoSuchMethodException ex) {         throw new RuntimeException(                 "Missing static main on " + className, ex);     } catch (SecurityException ex) {         throw new RuntimeException(                 "Problem getting static main on " + className, ex);     }     int modifiers = m.getModifiers();     if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {         throw new RuntimeException(                 "Main method is not public and static on " + className);     }     /*      * This throw gets caught in ZygoteInit.main(), which responds      * by invoking the exception's run() method. This arrangement      * clears up all the stack frames that were required in setting      * up the process.      */     throw new ZygoteInit.MethodAndArgsCaller(m, argv); }

可见在invokeStaticMain函数中最后抛出了异常。这相当于一个“特殊的goto语句”!上面的cl = Class.forName函数,其实加载的就是SystemServer类。这个类名是从前文的parsedArgs.remainingArgs得来的,其值就是“com.android.server.SystemServer”。此处抛出的异常,会被本进程的catch语句接住,在那里才会执行SystemServer类的main()函数

如下图所示,新fork出的SystemServer子进程直接跳过了中间那句runSelectLoop(),去执行caller.run()去了,也就是说这个run函数是在子进程中执行的。

父进程Zygote在fork动作后,会退出startSystemServer()函数,并走到runSelectLoop(),从而进入一种循环监听状态,每当Activity Manager Service向它发出“启动新应用进程”的命令时,它又会fork一个子进程,并在子进程里抛出一个异常,这样子进程还是会跳转到catch一句。

现在看以下 SystemServer类的main函数:

frameworks/base/services/java/com/android/server/SystemServer.java

123456
/** * The main entry point from zygote. */public static void main(String[] args) {    new SystemServer().run();}

可见创建了SystemServer对象,并且执行其run函数:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
private void run() {        // If a device's clock is before 1970 (before 0), a lot of        // APIs crash dealing with negative numbers, notably        // java.io.File#setLastModified, so instead we fake it and        // hope that time from cell towers or NTP fixes it shortly.        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {            Slog.w(TAG, "System clock is before 1970; setting to 1970.");            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);        }        // Here we go!        Slog.i(TAG, "Entered the Android system server!");        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());        // In case the runtime switched since last boot (such as when        // the old runtime was removed in an OTA), set the system        // property so that it is in sync. We can't do this in        // libnativehelper's JniInvocation::Init code where we already        // had to fallback to a different runtime because it is        // running as root and we need to be the system user to set        // the property. http://b/11463182        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());        // Enable the sampling profiler.        if (SamplingProfilerIntegration.isEnabled()) {            SamplingProfilerIntegration.start();            mProfilerSnapshotTimer = new Timer();            mProfilerSnapshotTimer.schedule(new TimerTask() {                @Override                public void run() {                    SamplingProfilerIntegration.writeSnapshot("system_server", null);                }            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);        }        // Mmmmmm... more memory!        VMRuntime.getRuntime().clearGrowthLimit();        // The system server has to run all of the time, so it needs to be        // as efficient as possible with its memory usage.        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);        // Some devices rely on runtime fingerprint generation, so make sure        // we've defined it before booting further.        Build.ensureFingerprintProperty();        // Within the system server, it is an error to access Environment paths without        // explicitly specifying a user.        Environment.setUserRequired(true);        // Ensure binder calls into the system always run at foreground priority.        BinderInternal.disableBackgroundScheduling(true);        // Prepare the main looper thread (this thread).        android.os.Process.setThreadPriority(                android.os.Process.THREAD_PRIORITY_FOREGROUND);        android.os.Process.setCanSelfBackground(false);        Looper.prepareMainLooper();        // Initialize native services.        System.loadLibrary("android_servers");        nativeInit();        // Check whether we failed to shut down last time we tried.        // This call may not return.        performPendingShutdown();        // Initialize the system context.        createSystemContext();        // Create the system service manager.        mSystemServiceManager = new SystemServiceManager(mSystemContext);        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);        // Start services.        try {            startBootstrapServices();            startCoreServices();            startOtherServices();        } catch (Throwable ex) {            Slog.e("System", "******************************************");            Slog.e("System", "************ Failure starting system services", ex);            throw ex;        }        // For debug builds, log event loop stalls to dropbox for analysis.        if (StrictMode.conditionallyEnableDebugLogging()) {            Slog.i(TAG, "Enabled StrictMode for system server main thread.");        }        // Loop forever.        Looper.loop();        throw new RuntimeException("Main thread loop unexpectedly exited");    }

可见会初始化 native services.

12
System.loadLibrary("android_servers");nativeInit();

监听zygote socket

ZygoteInit的main()函数在调用完startSystemServer()之后,zygote进程会进一步走到runSelectLoop()

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {    ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();    FileDescriptor[] fdArray = new FileDescriptor[4];    fds.add(sServerSocket.getFileDescriptor());//------------------------sServerSocket就是zygote socket文件描述符    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);//-----------------------------fdArry中就包含了zygote socket文件描述符了            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) {//-----------------------------------------对应的zygote socket有数据可读            ZygoteConnection newPeer = acceptCommandPeer(abiList);            peers.add(newPeer);            fds.add(newPeer.getFileDescriptor());        } else {//-------------------------------------------------对应其他文件描述符有数据可读            boolean done;            done = peers.get(index).runOnce();            if (done) {                peers.remove(index);                fds.remove(index);            }        }    }}

在一个while循环中,不断调用selectReadable()。该函数是个native函数,对应C++层的com_android_internal_os_ZygoteInit_selectReadable()。

Android源码/frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp

1234567
static JNINativeMethod gMethods[] = {.................................................................        { "selectReadable", "([Ljava/io/FileDescriptor;)I",        (void *) com_android_internal_os_ZygoteInit_selectReadable },    { "createFileDescriptor", "(I)Ljava/io/FileDescriptor;",        (void *) com_android_internal_os_ZygoteInit_createFileDescriptor }};
1234567891011121314151617181920
static jint com_android_internal_os_ZygoteInit_selectReadable (JNIEnv *env, jobject clazz,                                                                          jobjectArray fds){    . . . . . .    int err;    do {        err = select (nfds, &fdset, NULL, NULL, NULL);    } while (err < 0 && errno == EINTR);    . . . . . .    for (jsize i = 0; i < length; i++) {        jobject fdObj = env->GetObjectArrayElement(fds, i);        . . . . . .        int fd = jniGetFDFromFileDescriptor(env, fdObj);        . . . . . .        if (FD_ISSET(fd, &fdset)) {            return (jint)i;        }    }    return -1;}

主要就是调用select()而已。在Linux的socket编程中,select()负责监视若干文件描述符的变化情况,我们常见的变化情况有:读、写、异常等等。

在zygote中,err = select (nfds, &fdset, NULL, NULL, NULL);一句的最后三个参数都为NULL,表示该select()操作只打算监视文件描述符的“读变化”,而且如果没有可读的文件,select()就维持阻塞状态。

在被监视的文件描述符数组(fds)中,第一个文件描述符对应着“zygote接收其他进程连接申请的那个socket(及sServerSocket)”,一旦它发生了变化,我们就尝试建立一个ZygoteConnection。

新创建的ZygoteConnection会被再次写入文件描述符数组(fds):

1
fds.add(newPeer.getFileDescriptor());

如果select动作发现文件描述符数组(fds)的其他文件描述符有东西可读了,说明有其他进程通过某个已建立好的ZygoteConnection发来了命令,此时我们需要调用runOnce()。

123456789101112131415161718192021222324252627282930313233343536
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {     String args[];    Arguments parsedArgs = null;    FileDescriptor[] descriptors;     . . . . . .        args = readArgumentList();//----------------------------------------------------------------        descriptors = mSocket.getAncillaryFileDescriptors();    . . . . . .     int pid = -1;    FileDescriptor childPipeFd = null;    FileDescriptor serverPipeFd = null;     try {        parsedArgs = new Arguments(args);        . . . . . .        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal,                 parsedArgs.seInfo, parsedArgs.niceName);    }     . . . . . .        if (pid == 0) {            // in child            IoUtils.closeQuietly(serverPipeFd);            serverPipeFd = null;            handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);            return true;        } else {            // in parent...pid of < 0 means failure            IoUtils.closeQuietly(childPipeFd);            childPipeFd = null;            return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);        }    . . . . . .}

runOnce()中从socket中读取参数数据的动作是由readArgumentList()完成的,该函数的代码如下

12345678910111213141516171819
private String[] readArgumentList()        throws IOException {    int argc;    . . . . . .        String s = mSocketReader.readLine();    . . . . . .        argc = Integer.parseInt(s);    . . . . . .    String[] result = new String[argc];    for (int i = 0; i < argc; i++) {        result[i] = mSocketReader.readLine();        if (result[i] == null) {            // We got an unexpected EOF.            throw new IOException("truncated request");        }    }    return result;}

AMS会想这个socke写入参数。AMS需要启动一个新进程时,会调用类似下面的句子:

123
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",                    app.processName, uid, uid, gids, debugFlags, mountExternal,                    app.info.targetSdkVersion, app.info.seinfo, null);

包括ActivityThread类名等重要信息的参数,最终就会通过socket传递给zygote。

runOnce()在读完参数之后,会进一步调用到handleChildProc()。该函数会间接抛出特殊的MethodAndArgsCaller异常,只不过此时抛出的异常携带的类名为ActivityThread,前面我们提到的类名是SystemServer。

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,                              FileDescriptor pipeFd, PrintStream newStderr)                             throws ZygoteInit.MethodAndArgsCaller {    closeSocket();//--------------------------------------------因为不是zygote进程了,所以肯定要先关闭socket了    ZygoteInit.closeServerSocket();    . . . . . .    if (parsedArgs.niceName != null) {        Process.setArgV0(parsedArgs.niceName);    }     if (parsedArgs.runtimeInit) {        if (parsedArgs.invokeWith != null) {            WrapperInit.execApplication(parsedArgs.invokeWith,                    parsedArgs.niceName, parsedArgs.targetSdkVersion,                    pipeFd, parsedArgs.remainingArgs);        } else {            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,                    parsedArgs.remainingArgs);        }    } else {        String className;        . . . . . .            className = parsedArgs.remainingArgs[0];        . . . . . .        String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1];        System.arraycopy(parsedArgs.remainingArgs, 1,                mainArgs, 0, mainArgs.length);         if (parsedArgs.invokeWith != null) {            WrapperInit.execStandalone(parsedArgs.invokeWith,                    parsedArgs.classpath, className, mainArgs);        } else {            ClassLoader cloader;            if (parsedArgs.classpath != null) {                cloader = new PathClassLoader(parsedArgs.classpath,                        ClassLoader.getSystemClassLoader());            } else {                cloader = ClassLoader.getSystemClassLoader();            }             try {                ZygoteInit.invokeStaticMain(cloader, className, mainArgs);//-----------------------很熟悉吧,忘了的话,往上看            } catch (RuntimeException ex) {                logAndPrintError(newStderr, "Error starting.", ex);            }        }    }}

Zygote进程实际上是利用fork()创建新进程。如果fork()出的新进程是system server,那么其最终执行的就是SystemServer类的main()函数,而如果fork()出的新进程是普通的用户进程的话,那么其最终执行的就是ActivityThread类的main()函数。


原文地址: http://www.iloveandroid.net/2015/09/21/Zygote_2/

0 0
原创粉丝点击