Skip to content

ABI进程选择

追踪 primaryCpuAbi、ABI override、instruction set、Zygote socket 匹配和 NativeBridge 条件。

基于android-17.0.0_r1
AndroidABIZygoteProcessList源码阅读

ABI进程选择 ​

应用进程位数不是由“设备是 64 位”直接决定,也不是看到 zygote64 就固定走 primary socket。ProcessList 先从 ABI override 或 ApplicationInfo.primaryCpuAbi 得到 requiredAbi,缺失时回退 Build.SUPPORTED_ABIS[0];再由 VMRuntime 推导 instruction set。ZygoteProcess 连接 primary/secondary Zygote,使用握手返回的 ABI list 执行 matches(abi),最终选择能处理 requiredAbi 的 socket。

1. 设备ABI列表 ​

源码文件:frameworks/base/core/java/android/os/Build.java

java
public static final String[] SUPPORTED_ABIS =
        getStringList("ro.product.cpu.abilist", ",");

public static final String[] SUPPORTED_32_BIT_ABIS =
        getStringList("ro.product.cpu.abilist32", ",");

public static final String[] SUPPORTED_64_BIT_ABIS =
        getStringList("ro.product.cpu.abilist64", ",");

数组有偏好顺序,第一个元素是对应列表的首选 ABI。它们描述设备能力,不是某个 APK 的最终 ABI;PMS 安装扫描会结合 APK native library 和 package 配置填充 primaryCpuAbi/secondaryCpuAbi。

2. requiredAbi决策 ​

源码文件:frameworks/base/services/core/java/com/android/server/am/ProcessList.java

java
String requiredAbi = abiOverride != null
        ? abiOverride
        : app.info.primaryCpuAbi;

if (requiredAbi == null) {
    requiredAbi = Build.SUPPORTED_ABIS[0];
}

String instructionSet = null;
if (app.info.primaryCpuAbi != null) {
    instructionSet = VMRuntime.getInstructionSet(
            requiredAbi);
}

app.setRequiredAbi(requiredAbi);
app.setInstructionSet(instructionSet);

ABI override 优先,常用于调试/特殊进程;否则使用 package 的 primaryCpuAbi。若包无 native ABI,使用设备首选 ABI启动 Java 进程。instructionSet 只有 package primaryCpuAbi 非空时才推导,因为纯 Java 包通常不需要 native bridge/ISA 特化。

3. ABI字段 ​

primaryCpuAbi 是当前进程默认使用的 native ABI;secondaryCpuAbi 表示包可能还安装另一套 native 库,但 ProcessList 此处不会自动在两者间随机选择。多进程/ABI override、WebView Zygote 或 app zygote 可能改变最终 requiredAbi;普通应用默认沿 primaryCpuAbi。

4. Zygote握手匹配 ​

源码文件:frameworks/base/core/java/android/os/ZygoteProcess.java

java
boolean matches(String abi) {
    return mAbiList.contains(abi);
}

private ZygoteState openZygoteSocketIfNeeded(
        String abi) throws ZygoteStartFailedEx {
    attemptConnectionToPrimaryZygote();
    if (primaryZygoteState.matches(abi)) {
        return primaryZygoteState;
    }

    if (mZygoteSecondarySocketAddress != null) {
        attemptConnectionToSecondaryZygote();
        if (secondaryZygoteState.matches(abi)) {
            return secondaryZygoteState;
        }
    }
    throw new ZygoteStartFailedEx(
            "Unsupported zygote ABI: " + abi);
}

客户端先连 primary 并检查真实 ABI list;只有不匹配才连 secondary。primary/secondary 是连接优先级和 init 配置角色,不应等同于 64/32 固定别名。

5. ISA与桥接 ​

源码文件:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

cpp
bool need_pre_initialize_native_bridge =
        !is_system_server
        && instruction_set.has_value()
        && android::NativeBridgeAvailable()
        && !android::NativeBridgeInitialized()
        && android::NeedsNativeBridge(
                instruction_set.value().c_str());

if (need_pre_initialize_native_bridge) {
    android::PreInitializeNativeBridge(
            app_data_dir.has_value()
                    ? app_data_dir.value().c_str()
                    : nullptr,
            instruction_set.value().c_str());
}

instruction set 不等于 ABI 字符串,但由 ABI 映射得到。目标 ISA 与当前 runtime 不兼容且设备提供 NativeBridge 时,在 specialization 前预初始化;app zygote 已初始化时跳过。SystemServer 不走 NativeBridge 分支。

6. 专用Zygote ​

java
if (hostingRecord.usesWebviewZygote()) {
    startWebView(..., requiredAbi, instructionSet, ...);
} else if (hostingRecord.usesAppZygote()) {
    appZygote.startProcess(...,
            requiredAbi, instructionSet, ...);
} else {
    Process.start(...,
            requiredAbi, instructionSet, ...);
}

requiredAbi/instructionSet 会传给三种父进程路径,但每个父 Zygote 有自己的 accepted ABI list。WebView/app zygote 不支持该 ABI 时,启动失败,不会无条件回退 regular Zygote,因为父进程隔离语义已经由 HostingRecord 决定。

7. 失败与排查 ​

  • primaryCpuAbi 错误:检查 PMS native library 扫描和 package metadata;
  • ABI override 错误:ProcessList 会优先使用并导致 unsupported ABI;
  • 两个 Zygote 都不匹配:Unsupported zygote ABI;
  • instructionSet 为空:纯 Java 包通常正常,不应直接判错;
  • NativeBridge 失败:查目标 ISA、bridge 配置和 app data dir;
  • WebView/AppZygote 不匹配:查专用 Zygote accepted ABI,不应只看 regular Zygote。

8. 导航与后续 ​

bash
# ProcessList 的 requiredAbi、instructionSet 和三类 Zygote 分流。
rg -n "requiredAbi|primaryCpuAbi|abiOverride|getInstructionSet|usesWebviewZygote|usesAppZygote" \
  frameworks/base/services/core/java/com/android/server/am/ProcessList.java

# 设备 ABI 列表和 32/64 判断。
rg -n "SUPPORTED_ABIS|SUPPORTED_32_BIT_ABIS|SUPPORTED_64_BIT_ABIS|is64BitAbi" \
  frameworks/base/core/java/android/os/Build.java

# Zygote socket 匹配与 NativeBridge。
rg -n "matches\(|openZygoteSocketIfNeeded|Unsupported zygote ABI|NeedsNativeBridge|PreInitializeNativeBridge" \
  frameworks/base/core/java/android/os/ZygoteProcess.java \
  frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

下一篇将进入 Zygote LocalSocket 通信和环境 fd 的运行时连接模型;不会重复 ABI 决策。