Android應(yīng)用程序進程啟動過程的源代碼分析(六)
上文從peers.get(index)得到的是一個ZygoteConnection對象,表示一個Socket連接。
因此,接下來就是調(diào)用ZygoteConnection.runOnce函數(shù)進一步處理了。
Step 6. ZygoteConnection.runOnce
這個函數(shù)定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
- [java] view plaincopyclass ZygoteConnection {
- ......
- boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
- String args[];
- Arguments parsedArgs = null;
- FileDescriptor[] descriptors;
- try {
- args = readArgumentList();
- descriptors = mSocket.getAncillaryFileDescriptors();
- } catch (IOException ex) {
- ......
- 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) {
- ......
- } catch (ZygoteSecurityException ex) {
- ......
- }
- 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);
- }
- }
- ......
- }
真正創(chuàng)建進程的地方就是在這里了:
- [java] view plaincopypid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
有Linux開發(fā)經(jīng)驗的讀者很容易看懂這個函數(shù)調(diào)用,這個函數(shù)會創(chuàng)建一個進程,而且有兩個返回值,一個是在當前進程中返回的,一個是在新創(chuàng)建的進程中 返回,即在當前進程的子進程中返回,在當前進程中的返回值就是新創(chuàng)建的子進程的pid值,而在子進程中的返回值是0。因為我們只關(guān)心創(chuàng)建的新進程的情況, 因此,我們沿著子進程的執(zhí)行路徑繼續(xù)看下去:
- [java] view plaincopy if (pid == 0) {
- // in child
- handleChildProc(parsedArgs, descriptors, newStderr);
- // should never happen
- return true;
- } else { /* pid != 0 */
- ......
- }
這里就是調(diào)用handleChildProc函數(shù)了。