Step 5. ZygoteInit.runSelectLoopMode
這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:
當Step 4将資料通過Socket接口發送出去後,就會下面這個語句:
這裡從peers.get(index)得到的是一個ZygoteConnection對象,表示一個Socket連接配接,是以,接下來就是調用ZygoteConnection.runOnce函數進一步處理了。
Step 6. ZygoteConnection.runOnce
這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java檔案中:
真正建立程序的地方就是在這裡了:
有Linux開發經驗的讀者很容易看懂這個函數調用,這個函數會建立一個程序,而且有兩個傳回值,一個是在目前程序中傳回的,一個是在新建立的程序中傳回,即在目前程序的子程序中傳回,在目前程序中的傳回值就是新建立的子程序的pid值,而在子程序中的傳回值是0。因為我們隻關心建立的新程序的情況,是以,我們沿着子程序的執行路徑繼續看下去:
這裡就是調用handleChildProc函數了。
Step 7. ZygoteConnection.handleChildProc
由于在前面的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 {
// 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("--")) {
} 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);
}
}
這裡有兩個關鍵的函數調用,一個是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
<b>[java]</b> view plaincopy
public static final native void zygoteInitNative();
}
這裡可以看出,函數zygoteInitNative是一個Native函數,實作在frameworks/base/core/jni/AndroidRuntime.cpp檔案中:
<b>[cpp]</b> view plaincopy
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); // one per process
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函數。