根Activity元件的啟動過程

小編發表於2019-03-04

圖例只描述了Activity元件在程式外的啟動過程,即從Launcher點選圖示啟動MainActivity的過程。

MainActivity的啟動過程涉及到了三個程式。MainActivity元件、LauncherActivity元件和ActivityManagerService元件分別執行在不同的程式中。

根Activity元件的啟動過程

在第23步中會首先建立程式,流程如下圖

根Activity元件的啟動過程

其中ActivityManagerService和Process執行在system_server程式中,啟動新的程式時,需要system_server與zygote程式進行socket通訊,從而fork出新的程式。執行RuntimeInit.zygoteInit() -> RuntimeInit.applicationInit() -> RuntimeInit.invokeStaticMain()

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        redirectLogStreams();

        commonInit();
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv, classLoader);
    }複製程式碼
**RuntimeInit.invokeStaticMain()**
//className的值是“android.app.ActivityThread”
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            ......  
        }

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ......
        } catch (SecurityException ex) {
            ......
        }
        ......
        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception`s run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }複製程式碼

注意
ActivityThread.main方法的執行是通過拋異常的方式執行的。丟擲MethodAndrArgsCaller異常,一直按照原路向上拋。在ZygoteInit.main方法中捕獲異常,並呼叫run方法反射執行ActivityThread.main方法

public class ZygoteInit {
    public static void main(String argv[]) {
        try {
            ......

            registerZygoteSocket(socketName);
            ......
            preload();
            ......
            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            // 處理異常
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }
}複製程式碼

相關文章