天天看點

Android應用程式程序啟動過程的源代碼分析(2)

    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-&gt;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函數。