这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
public class ZygoteInit { ...... /** * Runs the zygote process's select loop. Accepts new connections as * they happen, and reads commands from connections one spawn-request's * worth at a time. * * @throws MethodAndArgsCaller in a child process when a main() should * be executed. */ 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); } } } } ...... }
done = peers.get(index).runOnce();
class 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); } } ...... }
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits);
if (pid == 0) { // in child handleChildProc(parsedArgs, descriptors, newStderr); // should never happen return true; } else { /* pid != 0 */ ...... }
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
class ZygoteConnection { ...... private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller { ...... if (parsedArgs.runtimeInit) { RuntimeInit.zygoteInit(parsedArgs.remainingArgs); } else { ...... } } ...... }
-
public class RuntimeInit {
-
......
-
-
public static final void zygoteInit(String[] argv)
-
throws ZygoteInit.MethodAndArgsCaller {
-
// TODO: Doing this here works, but it seems kind of arbitrary. Find
-
// a better place. The goal is to set it up for applications, but not
-
// tools like am.
-
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
-
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
-
-
commonInit();
-
zygoteInitNative();
-
-
int curArg = 0;
-
for ( /* curArg */ ; curArg < argv.length; curArg++) {
-
String arg = argv[curArg];
-
-
if (arg.equals("--")) {
-
curArg++;
-
break;
-
} else if (!arg.startsWith("--")) {
-
break;
-
} else if (arg.startsWith("--nice-name=")) {
-
String niceName = arg.substring(arg.indexOf('=') + 1);
-
Process.setArgV0(niceName);
-
}
-
}
-
-
if (curArg == argv.length) {
-
Slog.e(TAG, "Missing classname argument to RuntimeInit!");
-
// let the process exit
-
return;
-
}
-
-
// Remaining arguments are passed to the start class's static main
-
-
String startClass = argv[curArg++];
-
String[] startArgs = new String[argv.length - curArg];
-
-
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
-
invokeStaticMain(startClass, startArgs);
-
}
-
-
......
-
}
-
public class RuntimeInit {
-
......
-
-
public static final native void zygoteInitNative();
-
-
......
-
}
-
static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
-
{
-
gCurRuntime->onZygoteInit();
-
}
-
static AndroidRuntime* gCurRuntime = NULL;
-
AndroidRuntime::AndroidRuntime()
-
{
-
......
-
-
assert(gCurRuntime == NULL); // one per process
-
gCurRuntime = this;
-
}
-
int main(int argc, const char* const argv[])
-
{
-
......
-
-
AppRuntime runtime;
-
-
......
-
}
-
class AppRuntime : public AndroidRuntime
-
{
-
......
-
-
};