Android4.4的zygote进程(下)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android4.4的zygote进程(下)相关的知识,希望对你有一定的参考价值。

3.2.4启动android系统服务——startSystemServer()

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

startSystemServer()的代码如下:

 

[java] view plain copy
 
  1. private static boolean startSystemServer()  
  2.         throws MethodAndArgsCaller, RuntimeException   
  3. {  
  4.     . . . . . .  
  5.     /* Hardcoded command line to start the system server */  
  6.     String args[] = {  
  7.         "--setuid=1000",  
  8.         "--setgid=1000",  
  9.         "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,  
  10.                         3001,3002,3003,3006,3007",  
  11.         "--capabilities=" + capabilities + "," + capabilities,  
  12.         "--runtime-init",  
  13.         "--nice-name=system_server",  
  14.         "com.android.server.SystemServer",  
  15.     };  
  16.     ZygoteConnection.Arguments parsedArgs = null;  
  17.     int pid;  
  18.     try {  
  19.         parsedArgs = new ZygoteConnection.Arguments(args);  
  20.         ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);  
  21.         ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);  
  22.   
  23.         // fork出系统服务对应的进程  
  24.         pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,  
  25.                                             parsedArgs.gids, parsedArgs.debugFlags, null,  
  26.                                             parsedArgs.permittedCapabilities,  
  27.                                             parsedArgs.effectiveCapabilities);  
  28.     } catch (IllegalArgumentException ex) {  
  29.         throw new RuntimeException(ex);  
  30.     }  
  31.   
  32.     // 对新fork出的系统进程,执行handleSystemServerProcess()  
  33.     if (pid == 0) {  
  34.         handleSystemServerProcess(parsedArgs);  
  35.     }  
  36.     return true;  
  37. }  

 

 
 args[]中的字符串  对应
 "--setuid=1000"  parsedArgs.uid
 "--setgid=1000"  parsedArgs.gid

 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,
1009,1010,1018,1021,1032,3001,3002,3003,3006,3007"

 parsedArgs.gids
 "--capabilities=" + capabilities + "," + capabilities  capabilitiesSpecified = true;
permittedCapabilities = Long.decode(capStrings[0]);
effectiveCapabilites = Long.decode(capString[1]);
 "--runtime-init"  parsedArgs.runtimeInit设为true
 "--nice-name=system_server"  parsedArgs.niceName
 "com.android.server.SystemServer"  parsedArgs.remainingArgs

 

3.2.4.1Zygote.forkSystemServer()

Zygote.forkSystemServer()的代码如下:
【libcore/dalvik/src/main/java/dalvik/system/Zygote.java】

 

[java] view plain copy
 
  1. public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,  
  2.         int[][] rlimits, long permittedCapabilities, long effectiveCapabilities)   
  3. {  
  4.     preFork();  
  5.     int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits,   
  6.                                      permittedCapabilities, effectiveCapabilities);  
  7.     postFork();  
  8.     return pid;  
  9. }  

 

其中的nativeForkSystemServer()是个native成员函数,其对应的C++层函数为Dalvik_dalvik_system_Zygote_forkSystemServer()。

【dalvik/vm/native/dalvik_system_Zygote.cpp】

 

[cpp] view plain copy
 
  1. const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {  
  2.     { "nativeFork", "()I",  
  3.       Dalvik_dalvik_system_Zygote_fork },  
  4.     { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;)I",  
  5.       Dalvik_dalvik_system_Zygote_forkAndSpecialize },  
  6.     { "nativeForkSystemServer", "(II[II[[IJJ)I",  
  7.       Dalvik_dalvik_system_Zygote_forkSystemServer },  
  8.     { NULL, NULL, NULL },  
  9. };  

 

 
[cpp] view plain copy
 
  1. static void Dalvik_dalvik_system_Zygote_forkSystemServer(  
  2.         const u4* args, JValue* pResult)  
  3. {  
  4.     pid_t pid;  
  5.     pid = forkAndSpecializeCommon(args, true);  
  6.   
  7.     if (pid > 0) {  
  8.         int status;  
  9.   
  10.         ALOGI("System server process %d has been created", pid);  
  11.         gDvm.systemServerPid = pid;  
  12.         if (waitpid(pid, &status, WNOHANG) == pid) {  
  13.             ALOGE("System server process %d has died. Restarting Zygote!", pid);  
  14.             kill(getpid(), SIGKILL);  
  15.         }  
  16.     }  
  17.     RETURN_INT(pid);  
  18. }  
forkAndSpecializeCommon()内部其实会调用fork(),而后设置gid、uid等信息。

3.2.4.2SystemServer的handleSystemServerProgress()函数

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

 

[java] view plain copy
 
  1. // 对新fork出的系统进程,执行handleSystemServerProcess()  
  2. if (pid == 0) {  
  3.     handleSystemServerProcess(parsedArgs);  
  4. }  

 

注意,调用handleSystemServerProcess()时,程序是运行在新fork出的进程中的。handleSystemServerProcess()的代码如下:

【frameworks/base/core/java/com/android/internal/os/ZygoteInit.java】

 

[java] view plain copy
 
  1. private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)  
  2.                                            throws ZygoteInit.MethodAndArgsCaller   
  3. {  
  4.     closeServerSocket();  
  5.     Libcore.os.umask(S_IRWXG | S_IRWXO);  
  6.   
  7.     if (parsedArgs.niceName != null) {  
  8.         Process.setArgV0(parsedArgs.niceName);  // niceName就是”system_server”  
  9.     }  
  10.   
  11.     if (parsedArgs.invokeWith != null) {  
  12.         WrapperInit.execApplication(parsedArgs.invokeWith,  
  13.                 parsedArgs.niceName, parsedArgs.targetSdkVersion,  
  14.                 null, parsedArgs.remainingArgs);  
  15.     } else {  
  16.         // 此时的remainingArgs就是”com.android.server.SystemServer”  
  17.         RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);  
  18.     }  
  19. }  

 

 
3.2.4.2.1closeServerSocket()

因为当前已经不是运行在zygote进程里了,所以zygote里的那个监听socket就应该关闭了。这就是closeServerSocket()的意义,其代码如下:

 

[java] view plain copy
 
  1. static void closeServerSocket()   
  2. {  
  3.     try {  
  4.         if (sServerSocket != null) {  
  5.             FileDescriptor fd = sServerSocket.getFileDescriptor();  
  6.             sServerSocket.close();  
  7.             if (fd != null) {  
  8.                 Libcore.os.close(fd);  
  9.             }  
  10.         }  
  11.     } catch (IOException ex) {  
  12.         Log.e(TAG, "Zygote:  error closing sockets", ex);  
  13.     } catch (libcore.io.ErrnoException ex) {  
  14.         Log.e(TAG, "Zygote:  error closing descriptor", ex);  
  15.     }  
  16.     sServerSocket = null;  
  17. }  

 

在handleSystemServerProcess()函数里,parsedArgs.niceName就是“system_server”,而且因为parsedArgs.invokeWith没有指定,所以其值为null,于是程序会走到RuntimeInit.zygoteInit()。
3.2.4.2.2RuntimeInit.zygoteInit()

RuntimeInit.zygoteInit()的代码如下:
【frameworks/base/core/java/com/android/internal/os/RuntimeInit.java】

 

[java] view plain copy
 
  1. public static final void zygoteInit(int targetSdkVersion, String[] argv)  
  2.         throws ZygoteInit.MethodAndArgsCaller   
  3. {  
  4.     if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");  
  5.     redirectLogStreams();  
  6.     commonInit();  
  7.     nativeZygoteInit();  
  8.     applicationInit(targetSdkVersion, argv);  
  9. }  

 

 
3.2.4.2.2.1.调用redirectLogStreams()

首先,在新fork出的系统进程里,需要重新定向系统输出流。

 

[java] view plain copy
 
  1. public static void redirectLogStreams()   
  2. {  
  3.     System.out.close();  
  4.     System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));  
  5.     System.err.close();  
  6.     System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));  
  7. }  

 

 
3.2.4.2.2.2.调用commonInit()

 

[java] view plain copy
 
  1. private static final void commonInit()   
  2. {  
  3.     . . . . . .  
  4.     Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());  
  5.   
  6.     TimezoneGetter.setInstance(new TimezoneGetter()   
  7.     . . . . . .  
  8.     . . . . . .  
  9.     String trace = SystemProperties.get("ro.kernel.android.tracing");  
  10.     . . . . . .  
  11.     initialized = true;  
  12. }  

 

当前正处于系统进程的主线程中,可以调用Thread.setDefaultUncaughtExceptionHandler()来设置一个默认的异常处理器,处理程序中的未捕获异常。其他的初始化动作,我们暂不深究。
3.2.4.2.2.3.调用nativeZygoteInit()

接下来调用的nativeZygoteInit()是个JNI函数,在AndroidRuntime.cpp文件中可以看到:
【frameworks/base/core/jni/AndroidRuntime.cpp】

 

[java] view plain copy
 
  1. static JNINativeMethod gMethods[] = {  
  2.     { "nativeFinishInit", "()V",  
  3.         (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },  
  4.     { "nativeZygoteInit", "()V",  
  5.         (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },  
  6.     { "nativeSetExitWithoutCleanup", "(Z)V",  
  7.         (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },  
  8. };  

 

nativeZygoteInit()对应的本地函数为com_android_internal_os_RuntimeInit_nativeZygoteInit()。
[java] view plain copy
 
  1. static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)  
  2. {  
  3.     gCurRuntime->onZygoteInit();  
  4. }  
gCurRuntime是C++层的AndroidRuntime类的静态变量。在AndroidRuntime构造之时,

gCurRuntime = this。不过实际调用的onZygoteInit()应该是AndroidRuntime的子类AppRuntime的:
【frameworks/base/cmds/app_process/App_main.cpp】

 

[java] view plain copy
 
  1. class AppRuntime : public AndroidRuntime  
  2. {  
  3.     . . . . . .  
  4.     virtual void onZygoteInit()  
  5.     {  
  6.         // Re-enable tracing now that we‘re no longer in Zygote.  
  7.         atrace_set_tracing_enabled(true);  
  8.   
  9.         sp<ProcessState> proc = ProcessState::self();  
  10.         ALOGV("App process: starting thread pool.\n");  
  11.         proc->startThreadPool();  
  12.     }  

 

里面构造了进程的ProcessState全局对象,而且启动了线程池。

ProcessState对象是典型的单例模式,它的self()函数如下:

 

[java] view plain copy
 
  1. sp<ProcessState> ProcessState::self()  
  2. {  
  3.     Mutex::Autolock _l(gProcessMutex);  
  4.     if (gProcess != NULL) {  
  5.         return gProcess;  
  6.     }  
  7.     gProcess = new ProcessState;  
  8.     return gProcess;  
  9. }  

 

ProcessState对于Binder通信机制而言非常重要,现在system server进程的PrecessState算是初始化完毕了。

我们整理一下思路,画一张startSystemServer()的调用关系图:

 

技术分享

 

接下来我们来讲上图中zygoteInit()调用的最后一行:applicationInit()。

3.2.4.2.2.4.调用applicationInit()

applicationInit()函数的代码如下:
【frameworks/base/core/java/com/android/internal/os/RuntimeInit.java】

[java] view plain copy
 
  1. private static void applicationInit(int targetSdkVersion, String[] argv)  
  2.         throws ZygoteInit.MethodAndArgsCaller   
  3. {  
  4.     nativeSetExitWithoutCleanup(true);  
  5.     VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);  
  6.     VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);  
  7.   
  8.     final Arguments args;  
  9.     try {  
  10.         args = new Arguments(argv);  
  11.     } catch (IllegalArgumentException ex) {  
  12.         Slog.e(TAG, ex.getMessage());  
  13.         return;  
  14.     }  
  15.     invokeStaticMain(args.startClass, args.startArgs);  
  16. }  

其中的invokeStaticMain()一句最为关键,它承担向外抛出“特殊异常”的作用。我们先画一张startSystemServer()的调用关系图:

技术分享

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

技术分享

 

如上图所示,新fork出的SystemServer子进程直接跳过了中间那句runSelectLoop(),径直跳转到caller.run()一步了。

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

我们可以把上面的示意图再丰富一下:

技术分享


还有一点需要说明一下,fork出的SystemServer进程在跳转到catch语句后,会执行SystemServer类的main()函数,而其他情况下,fork出的应用进程在跳转的catch语句后,则会执行ActivityThread类的main()函数。这个ActivityThread对于应用程序而言非常重要,但因为和本篇主题关系不大,我们就不在这里展开讲了。

3.2.4.3 SystemServer的main()函数

前文我们已经看到了,startSystemServer()创建的新进程在执行完applicationInit()之后,会抛出一个异常,并由新fork出的SystemServer子进程的catch语句接住,继而执行SystemServer类的main()函数。

那么SystemServer的main()函数又在做什么事情呢?其调用关系图如下:

 

技术分享


在Android4.4版本中,ServerThread已经不再继承于Thread了,它现在只是个辅助类,其命名还残留有旧代码的味道。在以前的Android版本中,ServerThread的确继承于Thread,而且在线程的run()成员函数里,做着类似addService、systemReady的工作。

 

因为本文主要是阐述zygote进程的,所以我们就不在这里继续细说system server进程啦,有兴趣的同学可以继续研究。我们还是回过头继续说zygote里的动作吧。

 

3.2.5监听zygote socket

3.2.5.1runSelectLoop()

ZygoteInit的main()函数在调用完startSystemServer()之后,会进一步走到runSelectLoop()。runSelectInit()的代码如下:
【frameworks/base/core/java/com/android/internal/os/ZygoteInit.java】

 

[java] view plain copy
 
  1. private static void runSelectLoop() throws MethodAndArgsCaller   
  2. {  
  3.     ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();  
  4.     ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();  
  5.     FileDescriptor[] fdArray = new FileDescriptor[4];  
  6.   
  7.     fds.add(sServerSocket.getFileDescriptor());  
  8.     peers.add(null);  
  9.   
  10.     int loopCount = GC_LOOP_COUNT;  
  11.     while (true) {  
  12.         int index;  
  13.   
  14.         if (loopCount <= 0) {  
  15.             gc();  
  16.             loopCount = GC_LOOP_COUNT;  
  17.         } else {  
  18.             loopCount--;  
  19.         }  
  20.   
  21.         try {  
  22.             fdArray = fds.toArray(fdArray);  
  23.             index = selectReadable(fdArray);  
  24.         } catch (IOException ex) {  
  25.             throw new RuntimeException("Error in select()", ex);  
  26.         }  
  27.   
  28.         if (index < 0) {  
  29.             throw new RuntimeException("Error in select()");  
  30.         } else if (index == 0) {  
  31.             ZygoteConnection newPeer = acceptCommandPeer();  
  32.             peers.add(newPeer);  
  33.             fds.add(newPeer.getFileDesciptor());  
  34.         } else {  
  35.             boolean done;  
  36.             done = peers.get(index).runOnce();  
  37.             if (done) {  
  38.                 peers.remove(index);  
  39.                 fds.remove(index);  
  40.             }  
  41.         }  
  42.     }  
  43. }  

 

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

【frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp】

 

[cpp] view plain copy
 
  1. static jint com_android_internal_os_ZygoteInit_selectReadable (JNIEnv *env, jobject clazz,   
  2.                                                                          jobjectArray fds)  
  3. {  
  4.     . . . . . .  
  5.     int err;  
  6.     do {  
  7.         err = select (nfds, &fdset, NULL, NULL, NULL);  
  8.     } while (err < 0 && errno == EINTR);  
  9.     . . . . . .  
  10.     for (jsize i = 0; i < length; i++) {  
  11.         jobject fdObj = env->GetObjectArrayElement(fds, i);  
  12.         . . . . . .  
  13.         int fd = jniGetFDFromFileDescriptor(env, fdObj);  
  14.         . . . . . .  
  15.         if (FD_ISSET(fd, &fdset)) {  
  16.             return (jint)i;  
  17.         }  
  18.     }  
  19.     return -1;  
  20. }  

 

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

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

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

 

[java] view plain copy
 
  1. // (index == 0)的情况  
  2.             ZygoteConnection newPeer = acceptCommandPeer();  
  3.             peers.add(newPeer);  
  4.             fds.add(newPeer.getFileDesciptor());  

 

看到了吗,新创建的ZygoteConnection会被再次写入文件描述符数组(fds)。

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

 

[java] view plain copy
 
  1. // (index > 0)的情况  
  2.             boolean done;  
  3.             done = peers.get(index).runOnce();  
  4.             if (done) {  
  5.                 peers.remove(index);  
  6.                 fds.remove(index);  
  7.             }  

 

建立ZygoteConnection的acceptCommandPeer()的代码如下:
[java] view plain copy
 
  1. private static ZygoteConnection acceptCommandPeer() {  
  2.     try {  
  3.         return new ZygoteConnection(sServerSocket.accept());  
  4.     } catch (IOException ex) {  
  5.         throw new RuntimeException(  
  6.                 "IOException during accept()", ex);  
  7.     }  
  8. }  
 
3.2.5.1.1ZygoteConnection的runOnce()

ZygoteConnection的runOnce()代码截选如下:

 

[java] view plain copy
 
  1. boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {  
  2.   
  3.     String args[];  
  4.     Arguments parsedArgs = null;  
  5.     FileDescriptor[] descriptors;  
  6.   
  7.     . . . . . .  
  8.         args = readArgumentList();  
  9.         descriptors = mSocket.getAncillaryFileDescriptors();  
  10.     . . . . . .   
  11.     int pid = -1;  
  12.     FileDescriptor childPipeFd = null;  
  13.     FileDescriptor serverPipeFd = null;  
  14.   
  15.     try {  
  16.         parsedArgs = new Arguments(args);  
  17.         . . . . . .  
  18.         pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,  
  19.                 parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal,   
  20.                 parsedArgs.seInfo, parsedArgs.niceName);  
  21.     }   
  22.     . . . . . .  
  23.         if (pid == 0) {  
  24.             // in child  
  25.             IoUtils.closeQuietly(serverPipeFd);  
  26.             serverPipeFd = null;  
  27.             handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);  
  28.             return true;  
  29.         } else {  
  30.             // in parent...pid of < 0 means failure  
  31.             IoUtils.closeQuietly(childPipeFd);  
  32.             childPipeFd = null;  
  33.             return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);  
  34.         }  
  35.     . . . . . .  
  36. }    

 

 
3.2.5.1.2readArgumentList()

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

 

[java] view plain copy
 
  1. private String[] readArgumentList()  
  2.         throws IOException   
  3. {  
  4.     int argc;  
  5.     . . . . . .  
  6.         String s = mSocketReader.readLine();  
  7.     . . . . . .  
  8.         argc = Integer.parseInt(s);  
  9.     . . . . . .  
  10.     String[] result = new String[argc];  
  11.     for (int i = 0; i < argc; i++) {  
  12.         result[i] = mSocketReader.readLine();  
  13.         if (result[i] == null) {  
  14.             // We got an unexpected EOF.  
  15.             throw new IOException("truncated request");  
  16.         }  
  17.     }  
  18.     return result;  
  19. }  

 

可是是谁在向这个socket写入参数的呢?当然是AMS啦。

我们知道,当AMS需要启动一个新进程时,会调用类似下面的句子

 

[java] view plain copy
 
  1. Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",  
  2.                     app.processName, uid, uid, gids, debugFlags, mountExternal,  
  3.                     app.info.targetSdkVersion, app.info.seinfo, null);  

 

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

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

 

[java] view plain copy
 
  1. private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,   
  2.                              FileDescriptor pipeFd, PrintStream newStderr)  
  3.                              throws ZygoteInit.MethodAndArgsCaller   
  4. {  
  5.     closeSocket();  
  6.     ZygoteInit.closeServerSocket();  
  7.     . . . . . .  
  8.     if (parsedArgs.niceName != null) {  
  9.         Process.setArgV0(parsedArgs.niceName);  
  10.     }  
  11.   
  12.     if (parsedArgs.runtimeInit) {  
  13.         if (parsedArgs.invokeWith != null) {  
  14.             WrapperInit.execApplication(parsedArgs.invokeWith,  
  15.                     parsedArgs.niceName, parsedArgs.targetSdkVersion,  
  16.                     pipeFd, parsedArgs.remainingArgs);  
  17.         } else {  
  18.             RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,  
  19.                     parsedArgs.remainingArgs);  
  20.         }  
  21.     } else {  
  22.         String className;  
  23.         . . . . . .  
  24.             className = parsedArgs.remainingArgs[0];  
  25.         . . . . . .  
  26.         String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1];  
  27.         System.arraycopy(parsedArgs.remainingArgs, 1,  
  28.                 mainArgs, 0, mainArgs.length);  
  29.   
  30.         if (parsedArgs.invokeWith != null) {  
  31.             WrapperInit.execStandalone(parsedArgs.invokeWith,  
  32.                     parsedArgs.classpath, className, mainArgs);  
  33.         } else {  
  34.             ClassLoader cloader;  
  35.             if (parsedArgs.classpath != null) {  
  36.                 cloader = new PathClassLoader(parsedArgs.classpath,  
  37.                         ClassLoader.getSystemClassLoader());  
  38.             } else {  
  39.                 cloader = ClassLoader.getSystemClassLoader();  
  40.             }  
  41.   
  42.             try {  
  43.                 ZygoteInit.invokeStaticMain(cloader, className, mainArgs);  
  44.             } catch (RuntimeException ex) {  
  45.                 logAndPrintError(newStderr, "Error starting.", ex);  
  46.             }  
  47.         }  
  48.     }  
  49. }  

 

 

4小结

至此,zygote进程就阐述完毕了。作为一个最原始的“受精卵”,它必须在合适的时机进行必要的细胞分裂。分裂动作也没什么大的花样,不过就是fork()新进程而已。如果fork()出的新进程是system server,那么其最终执行的就是SystemServer类的main()函数,而如果fork()出的新进程是普通的用户进程的话,那么其最终执行的就是ActivityThread类的main()函数。有关ActivityThread的细节,我们有时间再深入探讨,这里就不细说了。

本篇文章和我的上一篇文章《Android4.4的init进程》可以算是姊妹篇啦。读完这两篇文章,我相信大家对Android的启动流程能有一些大面上的认识了。

转自http://blog.csdn.net/codefly/article/details/48413829

以上是关于Android4.4的zygote进程(下)的主要内容,如果未能解决你的问题,请参考以下文章

Android4.4的zygote进程(上)

Android4.4的zygote进程(上)

Dalvik虚拟机和Art虚拟机

Zygote进程——Zygote的分裂

Android Zygote进程

Android4.4的init进程