这是罗升阳《Android 系统源代码》一书中第12章,Android 应用程序进程的启动过程,的摘要;
当 ActivityMangerService 启动一个应用程序组件时,如果发现这个组件所需要的进程没有启动,就会请求 Zygote 启动新的进程。Zygote 通过复制自身的方式创建一个新的进程,同时也会获取一个虚拟机实例;
应用程序进程启动过程中,除了获得一个虚拟机实例外,还获得一个 Binder 线程池和一个消息循环。
当 ActivityManagerService 创建一个新的进程是,会调用 ActivityManagerService.startProcessLocked 方法向 Zygote 发送一个创建进程请求;
Zygote.forkAndSpecialize(...) 通过调用native 方法 nativeForkAndSpecialize(...) ,fork 一个新的进程;
ZygoteConnection.handleChildProc(...) 启动新的进程;
static void invokeStaticMain(ClassLoader loader, String className, String[] argv) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; try { cl = loader.loadClass(className); } catch (ClassNotFoundException ex) { throw new RuntimeException("Missing class when invoking static main " + className, ex); } Method m; try { // 通过反射进入获取ActivityThread 类的 main 方法 m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { throw new RuntimeException("Missing static main on " + className, ex); } catch (SecurityException ex) { throw new RuntimeException("Problem getting static main on " + className, ex); } int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { throw new RuntimeException("Main method is not public and static on " + className); } /* * 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. */ // 抛出 caller 异常,在 ZygoteInit 的 main 方法里捕获 throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
public static void main(String argv[]) { ····· } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { ··· } }
public static class MethodAndArgsCaller extends Exception implements Runnable { /** method to call */ private final Method mMethod; /** argument array */ private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { // 调用 ActivityThread 类的 main 方法 mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { ··· } } }
public static void main(String[] args) { ··· Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); ·· Looper.loop(); ··· }