Process.start
Process.start() 不是进程创建策略的 owner。真正的参数决策发生在 AMS 的 ProcessList:它根据 ProcessRecord、HostingRecord、ABI、存储隔离、compat changes、top-app 和 zygote policy 选择 WebView Zygote、App Zygote 或普通 Zygote。android.os.Process.start() 只选择 Java/native Zygote backend 并完整透传参数,返回 pid 和 wrapper 状态。
1. ProcessList入口
源码文件:frameworks/base/services/core/java/com/android/server/am/ProcessList.java
final Process.ProcessStartResult startResult;
boolean regularZygote = false;
long forkTimeNs = SystemClock.uptimeNanos();
final boolean useDeliQueue =
mPlatformCompat.getUseDeliQueue(app.info);
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(...);
} else if (hostingRecord.usesAppZygote()) {
AppZygote appZygote =
createAppZygoteForProcessIfNeeded(app);
startResult = appZygote.startProcess(...);
} else {
regularZygote = true;
startResult = Process.start(...);
app.mProcessGroupCreated = true;
}HostingRecord 决定父 Zygote 类型;compat 决定 deli queue 等运行参数。只有普通 Zygote 路径直接调用 Process.start(),WebView/App Zygote 使用专用 wrapper。返回后,ProcessList 记录 fork timestamp 并继续创建/确认进程组。
2. 存储隔离参数
StorageManagerInternal storage =
LocalServices.getService(
StorageManagerInternal.class);
if (needsStorageDataIsolation(storage, app)) {
if (pkgDataInfoMap != null
&& storage.isFuseMounted(userId)) {
bindMountAppStorageDirs = true;
} else {
app.setBindMountPending(true);
bindMountAppStorageDirs = false;
}
}
if (app.isolated) {
pkgDataInfoMap = null;
allowlistedAppDataInfoMap = null;
}ProcessList 在 fork 前计算 CE/DE、Android/data/obb 和 FUSE mount 参数。isolated process 不应挂载自身 app data,因此清空 data info map。Fuse 未就绪时标记 bind mount pending,让后续解锁/恢复路径处理,而不是阻塞当前 fork。
3. 启动参数
源码文件:frameworks/base/core/java/android/os/Process.java
public static ProcessStartResult start(
String processClass, String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion, String seInfo,
String abi, String instructionSet,
String appDataDir, String invokeWith,
String packageName, int zygotePolicyFlags,
boolean isTopApp,
long[] disabledCompatChanges,
long[] enabledCompatChanges,
boolean useDeliQueue,
Map<String, Pair<String, Long>> pkgDataInfoMap,
Map<String, Pair<String, Long>> allowlistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
boolean bindMountSystemOverrides,
long startSeq, String[] zygoteArgs) {
...
}参数分成五类:Java 入口与进程名;uid/gid/groups/SELinux;runtime/SDK/compat;ABI/instruction set;数据目录、mount、top-app、policy、start sequence。startSeq 用于 AMS 把返回 pid 与当前启动请求关联,防止旧进程启动结果覆盖新请求。
4. Backend选择
boolean isNative = android.os.Flags.nativeFrameworkPrototype()
&& (zygotePolicyFlags
& ZYGOTE_POLICY_FLAG_NATIVE_PROCESS) != 0;
IZygoteProcess process = isNative
? NATIVE_ZYGOTE_PROCESS
: ZYGOTE_PROCESS;
return process.start(
processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal,
targetSdkVersion, seInfo, abi,
instructionSet, appDataDir, invokeWith,
packageName, zygotePolicyFlags, isTopApp,
disabledCompatChanges, enabledCompatChanges,
useDeliQueue, pkgDataInfoMap,
allowlistedDataInfoMap, bindMountAppsData,
bindMountAppStorageDirs,
bindMountSystemOverrides, startSeq, zygoteArgs);native framework prototype flag 与 policy bit 同时满足时选择 NativeZygoteProcess,否则选择普通 ZygoteProcess。Backend 选择不改变参数 owner;两者都实现 IZygoteProcess.start() 契约。
5. 返回结果
public static final class ProcessStartResult {
public int pid;
public boolean usingWrapper;
}成功结果只包含新 pid 和是否使用 wrapper;失败不会返回负 pid,而是抛异常。ProcessList 随后根据路径处理进程组:普通 Zygote 已负责创建组,WebView/App Zygote 可能由 SystemServer 额外调用 Process.createProcessGroup()。
6. fork后的存储准备
if (bindMountAppStorageDirs) {
storageManagerInternal.prepareStorageDirs(
userId, pkgDataInfoMap.keySet(),
app.processName);
}
checkSlow(startTime,
"startProcess: returned from zygote!");
return startResult;prepareStorageDirs() 被刻意放在 Process.start() 返回后,源码注释说明目录未缓存时会拖慢进程启动;先触发 fork,再异步/后置准备目录,可以让 Zygote 使用缓存而不等待。该优化不改变 mount 决策,失败仍需在存储恢复路径处理。
7. 失败与状态边界
- 参数准备失败:ProcessList 尚未调用 Zygote;
- ABI/parent Zygote 选择失败:ZygoteProcess 抛异常,ProcessStartResult 不存在;
- native fork 失败:通过 Zygote 协议错误返回并转异常;
- pid 返回后进程立即死亡:
ProcessStartResult.pid曾有效,但后续 attach 超时/死亡路径清理; - 进程组创建失败:WebView/App Zygote 路径可能在 fork 成功后再失败;
- storage bind pending:进程可先启动,但数据挂载状态尚未完成。
8. 导航与后续
# AMS/ProcessList 参数准备、Zygote 分流和返回处理。
rg -n "usesWebviewZygote|usesAppZygote|Process.start\(|bindMountAppStorageDirs|ProcessStartResult|createProcessGroup" \
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
# Process.start 参数契约、backend 选择和返回类型。
rg -n "ProcessStartResult start\(|NATIVE_ZYGOTE_PROCESS|ZYGOTE_PROCESS|nativeFrameworkPrototype|class ProcessStartResult" \
frameworks/base/core/java/android/os/Process.java下一篇将展开 ZygoteProcess.start() 如何把这些字段编码成文本命令、选择 ABI socket、发送并读取 pid;不会重复 ProcessList 的策略计算。
