应用程序进程启动流程

基于Android U

ATMS发送启动应用程序进程请求

1. ATMS处理启动应用程序基本数据

由根Activity启动流程可知,应用程序进程不存在时,会通过ActivityTaskManagerService#startProcessAsync()创建新进程。

ATMS想要启动应用程序进程,就需要向Zygote进程发送创建应用程序进程的请求,ATMS会通过调用startProcessLocked()向Zygote进程发送请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
try {
...
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
} finally {
...
}
}

ActivityManagerInternal::startProcess,”::”是Java8新增特性,相当于调用了ActivityManagerInternal的startProcess()方法。而ActivityManagerInternal是一个抽象类,它是Activity管理器本地服务接口,它的实现为AMS的内部类LocalService。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java$LocalService
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
...
synchronized (ActivityManagerService.this) {
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
} finally {
...
}
}

接着调用AMS的startProcessLocked()方法。

1
2
3
4
5
6
7
8
9
10
11
12
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
null /* sdkSandboxClientAppPackage */,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}

将启动进程任务转发给mProcessList,mProcessList是一个ProcessList对象,ProcessList是处理Activity进程的管理类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.uptimeMillis();
ProcessRecord app;
...

if (app == null) {
checkSlow(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox,
sdkSandboxUid, sdkSandboxClientAppPackage, hostingRecord); // 1
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
return null;
}
app.mErrorState.setCrashHandler(crashHandler);
app.setIsolatedEntryPoint(entryPoint);
app.setIsolatedEntryPointArgs(entryPointArgs);
if (predecessor != null) {
app.mPredecessor = predecessor;
predecessor.mSuccessor = app;
}
checkSlow(startTime, "startProcess: done creating new process record");
} else {
...
}

...
final boolean success =
startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
checkSlow(startTime, "startProcess: done starting proc!"); // 2
return success ? app : null;
}

注释1处创建了ProcessRecord对象,它保存了当前正在运行的特定进程的完整信息,也就是需要启动的应用程序进程。接着注释2处继续调用startProcessLocked()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, String abiOverride) {
return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
abiOverride);
}

boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
String abiOverride) {
...

try {
...
int uid = app.uid; // 1
...
if (!app.isolated) {
...
gids = computeGidsForProcess(mountExternal, uid, permGids, externalStorageAccess); // 2
}
...
final String entryPoint = "android.app.ActivityThread"; // 3

return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startUptime, startElapsedTime); // 4
} catch (RuntimeException e) {
...
}
}

注释1处获取了应用程序的用户id;

注释2处获取了用户组id;

注释3处给entrypoint赋值为”android.app.ActivityThread”,这个值就是应用程序进程主线程的类名;

注释4处接着调用startProcessLocked();

此外,还设置了App进程挂载外部空间的模式、RuntimeFlags、abi架构等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startUptime, long startElapsedTime) {
...

if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { // 异步启动进程
...
mService.mProcStartHandler.post(() -> handleProcessStart(
app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
requiredAbi, instructionSet, invokeWith, startSeq));
return true;
} else {
try {
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startUptime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
} catch (RuntimeException e) {
...
}
return app.getPid() > 0;
}
}

针对AMS采用同步或者异步的启动方式做了一些工作,最终都会调用startProcess()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
int mountExternal, String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
try {
...
final Process.ProcessStartResult startResult;
...
if (hostingRecord.usesWebviewZygote()) { // 1
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
app.getDisabledCompatChanges(),
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
} else if (hostingRecord.usesAppZygote()) { // 2
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

// We can't isolate app data and storage data as parent zygote already did that.
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,
false, false,
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
} else { // 3
regularZygote = true;
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
// By now the process group should have been created by zygote.
app.mProcessGroupCreated = true;
}

...
return startResult;
} finally {
...
}
}

startProcess()会判断由哪个Zygote来创建我们的App进程。一般情况下,不指定时,使用默认Zygote。

注释1处由WebviewZygote创建进程;

注释2处由AppZygote创建进程;

注释3处由默认的Zygote创建进程,调用Process类的start()方法,Process是用于管理操作系统进程的工具类。

2. Process处理启动参数到Zygote进程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
frameworks/base/core/java/android/os/Process.java
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>> pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>> whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs)
}

Process#start()方法把进程的启动工作转发给了ZygoteProcess。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
frameworks/base/core/java/android/os/ZygoteProcess.java
public final Process.ProcessStartResult start(@NonNull final String processClass,
final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>> pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>> allowlistedDataInfoList,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
// TODO (chriswailes): Is there a better place to check this value?
if (fetchUsapPoolEnabledPropWithMinInterval()) {
informZygotesOfUsapPoolStatus();
}

try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
...
}
}

ZygoteProcess#start()又调用了startViaZygote()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
frameworks/base/core/java/android/os/ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
@Nullable final String niceName,
final int uid, final int gid,
@Nullable final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
boolean startChildZygote,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>> pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>> allowlistedDataInfoList,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<>();

argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
... // 设置一系列参数

synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags, argsForZygote);
}
}

设置启动参数,然后调用zygoteSendArgsAndGetResult(),该方法的第一个参数又调用了openZygoteSocketIfNeeded()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
frameworks/base/core/java/android/os/ZygoteProcess.java
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
attemptConnectionToPrimaryZygote(); // 1

if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}

if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary.
attemptConnectionToSecondaryZygote(); // 2

if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
}

throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}

private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
...

if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
try {
return attemptUsapSendArgsAndGetResult(zygoteState, msgStr); // 3
} catch (IOException ex) {
...
}
}

return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); // 4
}

注释1和注释2处,如果连接Zygote主模式返回的ZygoteState与启动应用程序所需的abi不匹配,则连接Zygote辅模式。两个方法逻辑基本相同。

注释3和注释4处都传入了zygoteState,ZygoteState是ZygoteProcess的静态内部类,保存了与Zygote进行通信的状态,而它的返回是由openZygoteSocketIfNeeded()处理的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
frameworks/base/core/java/android/os/ZygoteProcess.java
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress); // 1

maybeSetApiDenylistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
}

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
// 获取服务端(Zygote)输出流
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
// 获取服务端(Zygote)输入流
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

// 将参数写入Zygote
zygoteWriter.write(msgStr);
zygoteWriter.flush();

// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
Process.ProcessStartResult result = new Process.ProcessStartResult();
// 获取Zygote返回的结果
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();

if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}

return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}

注释1处调用ZygoteState的connect()方法打开Socket连接,mZygoteSocketAddress是名称为zygote的Socket服务。

attemptZygoteSendArgsAndGetResult()主要是通过socket通道向Zygote进程发送一个参数列表,然后进入阻塞等待状态,直到远端的socket服务端发送回来新创建的进程pid才返回。

Zygote接收请求并创建应用程序进程

1. Zygote接收请求

Zygote是通过fork自身来创建其他进程的。在ZygoteInit#main()中根据传递进来的参数,判断是启动什么类型的进程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
...
Runnable caller; // 1
try {
...
boolean startSystemServer = false; // 2
String zygoteSocketName = "zygote"; // 3
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) { // 4
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}

final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
...

Zygote.initNativeState(isPrimaryZygote); // 5

...

zygoteServer = new ZygoteServer(isPrimaryZygote); // 6

if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // 7

// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}

Log.i(TAG, "Accepting command socket connections");

// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList); // 8
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with fatal exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}

// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run(); // 9
}
}

注释1处创建了一个Runnable类型的请求对象代表此次请求Zygote获取应用进程的对象;

注释2、4、7处如果是SystemServer进程,就启动SystemServer,如果不是就启动其他应用程序进程;

注释3处设置Socket连接名称为zygote;

注释5处初始化Zygote的状态环境,包括支持套接字的环境、安全环境等;

注释6处创建了ZygoteServer对象,它可以理解为Zygote支持Socket进程通信的服务端;

注释8处的runSelectLoop()是Zygote进程等待接收AMS请求启动应用程序进程的关键方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
...
while (true) {
...
if (pollReturnValue == 0) {
...
} else {
...
while (--pollIndex >= 0) {
...
if (pollIndex == 0) {
// Zygote server socket
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
try {
ZygoteConnection connection = peers.get(pollIndex);
boolean multipleForksOK = !isUsapPoolEnabled()
&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();
final Runnable command =
connection.processCommand(this, multipleForksOK); // 1
...
} catch (Exception e) {
...
} finally {
...
}

} else {
...
}
}
...
}
...
}
}

当有AMS的请求数据到来时,会调用注释1处的代码,即调用ZygoteConnection#processCommand()。

2. 获取应用程序进程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
ZygoteArguments parsedArgs;

try (ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket)) {
while (true) {
try {
parsedArgs = ZygoteArguments.getInstance(argBuffer);
// Keep argBuffer around, since we need it to fork.
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
...

if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
|| !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
// Continue using old code for now. TODO: Handle these cases in the other path.
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits,
parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName,
fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir,
parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList,
parsedArgs.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,
parsedArgs.mBindMountAppStorageDirs); // 1

try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();

zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;

return handleChildProc(parsedArgs, childPipeFd,
parsedArgs.mStartChildZygote); // 2
} else {
...
}
} finally {
...
}
} else {
...
}
}
}
...
}

注释1处fork子进程,参数为parsedArgs中存储的应用进程启动参数,返回值为pid。如果pid为0,说明当前代码逻辑运行在新创建的子进程(应用程序进程)中,这时就会调用注释2处handleChildProc()方法来处理应用程序进程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
frameworks/base/core/java/com/android/internal/os/Zygote.java
static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
boolean isTopApp, String[] pkgDataInfoList, String[] allowlistedDataInfoList,
boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
...
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
pkgDataInfoList, allowlistedDataInfoList, bindMountAppDataDirs,
bindMountAppStorageDirs);
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.mInvokeWith != null) {
...
} else {
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(
parsedArgs.mRemainingArgs /* classLoader */);
}
}
}

forkAndSpecialize()会通过native方法nativeForkAndSpecialize()与底层通信fork应用程序进程。

handleChildProc()继续调用ZygoteInit#zygoteInit()方法。

3. 创建应用程序的ActivityThread
1
2
3
4
5
6
7
8
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
ZygoteInit.nativeZygoteInit(); // 1
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader); // 2
}

注释1处会在新创建的应用程序进程中创建Binder线程池,当前应用程序就拥有了Binder通信的能力;

注释2处调用了RuntimeInit#applicationInit()。

1
2
3
4
5
6
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
return findStaticMain(args.startClass, args.startArgs, classLoader);
}

调用findStaticMain(),其中的args.startClass是android.app.ActivityThread。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;

try {
cl = Class.forName(className, true, classLoader); // 1
} catch (ClassNotFoundException ex) {
...
}

Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class }); // 2
} catch (NoSuchMethodException ex) {
...
} catch (SecurityException ex) {
...
}

...
return new MethodAndArgsCaller(m, argv); // 3
}

注释1处通过反射获得了android.app.ActivityThread类;

注释2处获得了ActivityThread的main()方法,并将main()方法传入注释3处的MethodAndArgsCaller类的构造方法中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
static class MethodAndArgsCaller 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 {
mMethod.invoke(null, new Object[] { mArgs }); // 1
} catch (IllegalAccessException ex) {
...
} catch (InvocationTargetException ex) {
...
}
}
}

该Runnable一路返回到本小节开头的注释9:caller.run()。caller.run()调用Method#invoke(),也就是ActivityThread#main()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
...
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);

if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");
}

ActivityThread是每个应用程序主线程的管理类。main()中创建了ActivityThread进程,并启动了消息循环队列,代表着当前进程的主线程已启动。

到此,应用程序进程启动完成。


应用程序进程启动流程
https://citrus-maxima.github.io/2024/03/10/应用程序进程启动流程/
作者
柚子树
发布于
2024年3月10日
许可协议