Step 5. ZygoteInit.runSelectLoopMode
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
-
public class ZygoteInit {
-
......
-
-
-
-
-
-
-
-
-
-
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;
-
-
-
-
-
-
-
-
-
-
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);
-
}
-
}
-
}
-
}
-
-
......
-
}
当Step 4将数据通过Socket接口发送出去后,就会下面这个语句:
-
done = peers.get(index).runOnce();
这里从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接,因此,接下来就是调用ZygoteConnection.runOnce函数进一步处理了。
Step 6. ZygoteConnection.runOnce
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
-
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;
-
}
-
-
......
-
-
-
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) {
-
-
handleChildProc(parsedArgs, descriptors, newStderr);
-
-
return true;
-
} else {
-
-
return handleParentProc(pid, descriptors, parsedArgs);
-
}
-
}
-
-
......
-
}
真正创建进程的地方就是在这里了:
-
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
-
parsedArgs.gids, parsedArgs.debugFlags, rlimits);
有Linux开发经验的读者很容易看懂这个函数调用,这个函数会创建一个进程,而且有两个返回值,一个是在当前进程中返回的,一个是在新创建的进程中返回,即在当前进程的子进程中返回,在当前进程中的返回值就是新创建的子进程的pid值,而在子进程中的返回值是0。因为我们只关心创建的新进程的情况,因此,我们沿着子进程的执行路径继续看下去:
-
if (pid == 0) {
-
-
handleChildProc(parsedArgs, descriptors, newStderr);
-
-
return true;
-
} else {
-
......
-
}
这里就是调用handleChildProc函数了。
Step 7. ZygoteConnection.handleChildProc
这个函数定义在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 {
-
......
-
}
-
}
-
-
......
-
}
由于在前面的Step 3中,指定了"--runtime-init"参数,表示要为新创建的进程初始化运行时库,因此,这里的parseArgs.runtimeInit值为true,于是就继续执行RuntimeInit.zygoteInit进一步处理了。
Step 8. RuntimeInit.zygoteInit
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
-
public class RuntimeInit {
-
......
-
-
public static final void zygoteInit(String[] argv)
-
throws ZygoteInit.MethodAndArgsCaller {
-
-
-
-
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
-
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
-
-
commonInit();
-
zygoteInitNative();
-
-
int curArg = 0;
-
for ( ; 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!");
-
-
return;
-
}
-
-
-
-
String startClass = argv[curArg++];
-
String[] startArgs = new String[argv.length - curArg];
-
-
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
-
invokeStaticMain(startClass, startArgs);
-
}
-
-
......
-
}
这里有两个关键的函数调用,一个是zygoteInitNative函数调用,一个是invokeStaticMain函数调用,前者就是执行Binder驱动程序初始化的相关工作了,正是由于执行了这个工作,才使得进程中的Binder对象能够顺利地进行Binder进程间通信,而后一个函数调用,就是执行进程的入口函数,这里就是执行startClass类的main函数了,而这个startClass即是我们在Step 1中传进来的"android.app.ActivityThread"值,表示要执行android.app.ActivityThread类的main函数。
我们先来看一下zygoteInitNative函数的调用过程,然后再回到RuntimeInit.zygoteInit函数中来,看看它是如何调用android.app.ActivityThread类的main函数的。
step 9. RuntimeInit.zygoteInitNative
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
-
public class RuntimeInit {
-
......
-
-
public static final native void zygoteInitNative();
-
-
......
-
}
这里可以看出,函数zygoteInitNative是一个Native函数,实现在frameworks/base/core/jni/AndroidRuntime.cpp文件中:
-
static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
-
{
-
gCurRuntime->onZygoteInit();
-
}
这里它调用了全局变量gCurRuntime的onZygoteInit函数,这个全局变量的定义在frameworks/base/core/jni/AndroidRuntime.cpp文件开头的地方:
-
static AndroidRuntime* gCurRuntime = NULL;
这里可以看出,它的类型为AndroidRuntime,它是在AndroidRuntime类的构造函数中初始化的,AndroidRuntime类的构造函数也是定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中:
-
AndroidRuntime::AndroidRuntime()
-
{
-
......
-
-
assert(gCurRuntime == NULL);
-
gCurRuntime = this;
-
}
那么这个AndroidRuntime类的构造函数又是什么时候被调用的呢?AndroidRuntime类的声明在frameworks/base/include/android_runtime/AndroidRuntime.h文件中,如果我们打开这个文件会看到,它是一个虚拟类,也就是我们不能直接创建一个AndroidRuntime对象,只能用一个AndroidRuntime类的指针来指向它的某一个子类,这个子类就是AppRuntime了,它定义在frameworks/base/cmds/app_process/app_main.cpp文件中:
-
int main(int argc, const char* const argv[])
-
{
-
......
-
-
AppRuntime runtime;
-
-
......
-
}
而AppRuntime类继续了AndroidRuntime类,它也是定义在frameworks/base/cmds/app_process/app_main.cpp文件中:
-
class AppRuntime : public AndroidRuntime
-
{
-
......
-
-
};
因此,在前面的com_android_internal_os_RuntimeInit_zygoteInit函数,实际是执行了AppRuntime类的onZygoteInit函数。