圖例只描述了Activity元件在程式外的啟動過程,即從Launcher點選圖示啟動MainActivity的過程。
MainActivity的啟動過程涉及到了三個程式。MainActivity元件、LauncherActivity元件和ActivityManagerService元件分別執行在不同的程式中。
在第23步中會首先建立程式,流程如下圖
其中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;
}
}
}複製程式碼