RuntimeInit.applicationInit
fork/specialization 完成后,子进程仍停留在 Zygote 的 Java 调用栈。RuntimeInit.applicationInit() 把进程切换到目标应用运行语义:禁用通用 shutdown hooks,设置 target SDK 和 compat changes,解析目标类与参数,反射检查 public static main(String[]),返回 MethodAndArgsCaller。对普通应用,目标类是 android.app.ActivityThread;其 main 再解析 start sequence/deli queue、准备 Looper并向 AMS attach。
1. 退出策略
源码文件:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(
int targetSdkVersion,
long[] disabledCompatChanges,
long[] enabledCompatChanges,
String[] argv,
ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
...
}Android 应用调用 System.exit() 时直接终止,不执行会关闭 Binder driver 的通用 runtime shutdown hooks。否则残留线程可能在进程尚未完全退出时访问已经关闭的 Binder 状态。这个开关在任何应用静态初始化前生效。
2. SDK与兼容状态
VMRuntime.getRuntime().setTargetSdkVersion(
targetSdkVersion);
VMRuntime.getRuntime().setDisabledCompatChanges(
disabledCompatChanges);
if (disabledCompatChanges != null
|| enabledCompatChanges != null) {
AppCompatCallbacks.install(
disabledCompatChanges,
enabledCompatChanges,
null, false, targetSdkVersion);
}target SDK 与 compat callbacks 在 Class.forName() 前安装,确保 ActivityThread 和应用类的静态初始化也按目标应用兼容规则运行。ActivityThread 后续 bind application 时会用更完整数据重新安装,但这里提供最早期基线。
3. Arguments解析
static class Arguments {
String startClass;
String[] startArgs;
private void parseArgs(String[] args) {
int curArg = 0;
for (; curArg < args.length; curArg++) {
String arg = args[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
}
}
if (curArg == args.length) {
throw new IllegalArgumentException(
"Missing classname argument to RuntimeInit!");
}
startClass = args[curArg++];
startArgs = Arrays.copyOfRange(
args, curArg, args.length);
}
}Arguments 跳过 RuntimeInit option 或显式 --,第一个非 option 是目标类,其余完整保留给 main。ZygoteProcess 把 processClass 之后的 start sequence/deli queue 放入这部分,因此参数顺序错误会改变消费者。
4. 静态main查找
Class<?> cl = Class.forName(
className, true, classLoader);
Method m = cl.getMethod(
"main", new Class[] { String[].class });
int modifiers = m.getModifiers();
if (!(Modifier.isStatic(modifiers)
&& Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on "
+ className);
}
return new MethodAndArgsCaller(m, argv);类加载强制初始化,并使用传入 classloader;普通应用通常传 null 使用 boot classpath 找 ActivityThread。类缺失、main 缺失、安全异常、修饰符错误分别转换为 RuntimeException,使子进程退出而不是带着不完整入口继续运行。
5. Runnable清栈
static class MethodAndArgsCaller implements Runnable {
@Override
public void run() {
try {
mMethod.invoke(null,
new Object[] { mArgs });
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}返回 Runnable 让 ZygoteInit 在退出进程准备栈后再执行 main。反射包装异常被拆回原始 RuntimeException/Error,ActivityThread.main 的真实崩溃不会被隐藏成通用 InvocationTargetException。
6. 应用主线程参数
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
long startSeq = 0;
for (int i = args.length - 1; i >= 0; --i) {
if (args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(
PROC_START_SEQ_IDENT.length()));
} else if (args[i].startsWith(
"--use-deliqueue=")) {
boolean useDeliQueue = Boolean.parseBoolean(
args[i].substring(
args[i].indexOf('=') + 1));
MessageQueue.setUseDeliQueue(useDeliQueue);
}
}
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
Looper.loop();startSeq 把子进程 attach 与 AMS 当前 ProcessRecord 启动请求关联;deli queue 必须在 prepareMainLooper() 创建 MessageQueue 前设置。ActivityThread 创建后调用 attach(false, startSeq) 通过 Binder 向 AMS 报到,最后进入主 Looper。
7. 失败边界
- 缺少 startClass:RuntimeInit 参数错误,ActivityThread 未加载;
- class/main 签名错误:反射入口失败,进程退出;
- compat 安装错误:可能在应用静态初始化前终止;
- startSeq 错误:AMS 可能拒绝/清理过期 attach;
- attachApplication 失败:ActivityThread 已创建但未绑定 AMS;
- Looper 退出:ActivityThread 抛致命 RuntimeException。
8. 导航与后续
# RuntimeInit 的退出策略、兼容状态、参数和反射入口。
rg -n "applicationInit|nativeSetExitWithoutCleanup|setTargetSdkVersion|AppCompatCallbacks|class Arguments|findStaticMain|MethodAndArgsCaller" \
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
# ActivityThread 的参数消费、Looper 和 AMS attach。
rg -n "public static void main|PROC_START_SEQ_IDENT|use-deliqueue|prepareMainLooper|attach\(false|Looper.loop" \
frameworks/base/core/java/android/app/ActivityThread.java下一篇将深入 ActivityThread.main() 和 attach(false) 的应用主线程建立;不会重复 RuntimeInit 的反射入口。
