Android应用程序进程启动过程的源代码分析(六)

上文从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接。

因此,接下来就是调用ZygoteConnection.runOnce函数进一步处理了。

Step 6. ZygoteConnection.runOnce

这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:

 
 
  1. [java] view plaincopyclass ZygoteConnection { 
  2.   ...... 
  3.   boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { 
  4.   String args[]; 
  5.   Arguments parsedArgs = null
  6.   FileDescriptor[] descriptors; 
  7.   try { 
  8.   args = readArgumentList(); 
  9.   descriptors = mSocket.getAncillaryFileDescriptors(); 
  10.   } catch (IOException ex) { 
  11.   ...... 
  12.   return true
  13.   } 
  14.   ...... 
  15.   /** the stderr of the most recent request, if avail */ 
  16.   PrintStream newStderr = null
  17.   if (descriptors != null && descriptors.length >= 3) { 
  18.   newStderr = new PrintStream( 
  19.   new FileOutputStream(descriptors[2])); 
  20.   } 
  21.   int pid; 
  22.   try { 
  23.   parsedArgs = new Arguments(args); 
  24.   applyUidSecurityPolicy(parsedArgs, peer); 
  25.   applyDebuggerSecurityPolicy(parsedArgs); 
  26.   applyRlimitSecurityPolicy(parsedArgs, peer); 
  27.   applyCapabilitiesSecurityPolicy(parsedArgs, peer); 
  28.   int[][] rlimits = null
  29.   if (parsedArgs.rlimits != null) { 
  30.   rlimits = parsedArgs.rlimits.toArray(intArray2d); 
  31.   } 
  32.   pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, 
  33.   parsedArgs.gids, parsedArgs.debugFlags, rlimits); 
  34.   } catch (IllegalArgumentException ex) { 
  35.   ...... 
  36.   } catch (ZygoteSecurityException ex) { 
  37.   ...... 
  38.   } 
  39.   if (pid == 0) { 
  40.   // in child 
  41.   handleChildProc(parsedArgs, descriptors, newStderr); 
  42.   // should never happen 
  43.   return true
  44.   } else { /* pid != 0 */ 
  45.   // in parent...pid of < 0 means failure 
  46.   return handleParentProc(pid, descriptors, parsedArgs); 
  47.   } 
  48.   } 
  49.   ...... 
  50.   } 

真正创建进程的地方就是在这里了:

 
 
  1. [java] view plaincopypid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, 
  2.   parsedArgs.gids, parsedArgs.debugFlags, rlimits); 

有Linux开发经验的读者很容易看懂这个函数调用,这个函数会创建一个进程,而且有两个返回值,一个是在当前进程中返回的,一个是在新创建的进程中 返回,即在当前进程的子进程中返回,在当前进程中的返回值就是新创建的子进程的pid值,而在子进程中的返回值是0。因为我们只关心创建的新进程的情况, 因此,我们沿着子进程的执行路径继续看下去:

 
 
  1. [java] view plaincopy if (pid == 0) { 
  2.   // in child 
  3.   handleChildProc(parsedArgs, descriptors, newStderr); 
  4.   // should never happen 
  5.   return true
  6.   } else { /* pid != 0 */ 
  7.   ...... 
  8.   } 

这里就是调用handleChildProc函数了。

THE END