Android系统的启动主要分为几个步骤:swapper -> init -> zygote -> systemserver -> launcher,这些步骤都大致分析了一下,系统启动后,接下来应用程序是如何启动的?启动一个应用程序首先要保证应用程序的进程已经被启动了。
AMS在启动应用程序时,会检查这个应用程序需要的应用程序进程是否存在,不存在就会先去请求Zygote进程启动需要启动的应用程序进程。
启动应用程序可分为两部分来看:1.AMS发送启动应用程序进程请求 2.Zygote收到请求并创建应用程序进程
环境参数:
- android-14.0.0_r27
- Ubuntu 22.04.5 LTS
在线源码网址:xrefandroid
Launcher启动过程
AMS发送启动应用程序进程请求
AMS想要启动应用程序进程,首先是需要向Zygote进程发送创建应用程序进程的请求,其入口点在AMS调用startProcessLocked方法:
@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 */);
}
会自动进入到ProcessList的startProcessLocked方法中去,此函数重载,需要根据上下文参数确认是哪一个函数:
@frameworks/base/services/core/java/com/android/server/am/ProcessList.java
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
String abiOverride) {
...
try {
final int userId = UserHandle.getUserId(app.uid);
try {
AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
//获取要创建的应用程序进程的用户ID
int uid = app.uid;
//对gids进程创建赋值
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
boolean externalStorageAccess = false;
if (!app.isolated) {
int[] permGids = null;
...
gids = computeGidsForProcess(mountExternal, uid, permGids, externalStorageAccess);
}
app.setMountMode(mountExternal);
...
String seInfo = updateSeInfo(app);
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startUptime, startElapsedTime);
} catch (RuntimeException e) {
...
mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
false, false, true, false, false, app.userId, "start failure");
return false;
}
}
跳转到了另外一个重载函数中去了,同时其中有一个参数entryPoint,其值为android.app.ActivityThread需要注意:
@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) {
//handleProcessStart中,也会走到startProcess方法中去
mService.mProcStartHandler.post(() -> handleProcessStart(
app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
requiredAbi, instructionSet, invokeWith, startSeq));
return true;
} else {
try {
//去启动应用程序进程,返回Process.ProcessStartResult
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);
}
...
return app.getPid() > 0;
}
}
private void handleProcessStart(final ProcessRecord app, final String entryPoint,
final int[] gids, final int runtimeFlags, int zygotePolicyFlags,
final int mountExternal, final String requiredAbi, final String instructionSet,
final String invokeWith, final long startSeq) {
final Runnable startRunnable = () -> {
try {
final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(),
entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags,
mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith,
app.getStartTime());
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
}
}
...
};
...
}
startProcessLocked函数最后都会走到startProcess函数中去:
@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 {
...
if (hostingRecord.usesWebviewZygote()) {
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()) {
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 {
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 {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
将进程用户ID,用户组ID,entryPoint等参数传进Process的start方法中去,其中entryPoint为android.app.ActivityThread,是应用程序进程主线程的类名:
@frameworks/base/core/java/android/os/Process.java
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();
/**
* @param processClass The class to use as the process's main entry point.
*/
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的start方法,其中ZygoteProcess是用于保持与Zygote进程的通信状态:
@frameworks/base/core/java/android/os/ZygoteProcess.java#start
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) {
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);
}
...
}
在ZygoteProcess的start方法中,调用了startViaZygote方法:
@frameworks/base/core/java/android/os/ZygoteProcess.java#startViaZygote
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<>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
argsForZygote.add("--mount-external-installer");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
argsForZygote.add("--mount-external-pass-through");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
argsForZygote.add("--mount-external-android-writable");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
//全是构建argsForZygote参数,省略了。
...
//"android.app.ActivityThread"放入数组
argsForZygote.add(processClass);
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);
}
}
首先创建了一个字符串列表argsForZygote, 然后向列表添加了很多参数,最后调用zygoteSendArgsAndGetResult方法,其中一个参数是openZygoteSocketIfNeeded函数的返回值:
@frameworks/base/core/java/android/os/ZygoteProcess.java#zygoteSendArgsAndGetResult
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
// Throw early if any of the arguments are malformed. This means we can
// avoid writing a partial response to the zygote.
for (String arg : args) {
// Making two indexOf calls here is faster than running a manually fused loop due
// to the fact that indexOf is an optimized intrinsic.
if (arg.indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx("Embedded newlines not allowed");
} else if (arg.indexOf('\r') >= 0) {
throw new ZygoteStartFailedEx("Embedded carriage returns not allowed");
}
}
String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
try {
return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
}
...
}
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
将启动参数args转化为了字符串后,会根据判断进入对应函数,主要都是将启动参数写入zygoteState中去,最后再转化为Process.ProcessStartResult:
@frameworks/base/core/java/android/os/ZygoteProcess.java
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
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();
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);
}
}
private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr)
throws ZygoteStartFailedEx, IOException {
try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
final BufferedWriter usapWriter =
new BufferedWriter(
new OutputStreamWriter(usapSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
final DataInputStream usapReader =
new DataInputStream(usapSessionSocket.getInputStream());
usapWriter.write(msgStr);
usapWriter.flush();
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = usapReader.readInt();
// USAPs can't be used to spawn processes that need wrappers.
result.usingWrapper = false;
if (result.pid >= 0) {
return result;
} else {
throw new ZygoteStartFailedEx("USAP specialization failed");
}
}
}
而zygoteState参数是由上面openZygoteSocketIfNeeded函数返回的:
@frameworks/base/core/java/android/os/ZygoteProcess.java#openZygoteSocketIfNeeded
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
//与zygote进程建立socket连接
attemptConnectionToPrimaryZygote();
//连接zygote主模式返回的ZygoteState是否与启动应用程序进程所需要的ABI匹配
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
//如果上面的不匹配,则尝试连接zygote的辅模式
if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary.
attemptConnectionToSecondaryZygote();
//连接zygote辅模式返回的ZygoteState是否与启动应用程序进程所需要的ABI匹配
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
会先用主模式去连接zygote,如果不符合要求,再使用辅模式去连接,两种连接方式使用的socket是不一样的:
/**
* Creates a ZygoteState for the primary zygote if it doesn't exist or has been disconnected.
*/
@GuardedBy("mLock")
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
//使用mZygoteSocketAddress,用的是Zygote.PRIMARY_SOCKET_NAME
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
maybeSetApiDenylistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
}
/**
* Creates a ZygoteState for the secondary zygote if it doesn't exist or has been disconnected.
*/
@GuardedBy("mLock")
private void attemptConnectionToSecondaryZygote() throws IOException {
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
//使用mZygoteSecondarySocketAddress,用的是Zygote.SECONDARY_SOCKET_NAME
secondaryZygoteState =
ZygoteState.connect(mZygoteSecondarySocketAddress,
mUsapPoolSecondarySocketAddress);
maybeSetApiDenylistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
}
}
public ZygoteProcess() {
mZygoteSocketAddress =
new LocalSocketAddress(Zygote.PRIMARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
mZygoteSecondarySocketAddress =
new LocalSocketAddress(Zygote.SECONDARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
...
}
可以看出主模式去连接zygote的socket用的是Zygote.PRIMARY_SOCKET_NAME,辅模式用的是Zygote.SECONDARY_SOCKET_NAME。
在zygote进程启动过程中,会去创建socket的服务端,具体是在zygote刚进Java框架层,在ZygoteInit的main方法中通过创建ZygoteServer对象去管理socket:
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#main
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
...
zygoteServer = new ZygoteServer(isPrimaryZygote);
...
//进入循环读取数据
Runnable caller = zygoteServer.runSelectLoop(abiList);
//执行Runnable的里面的run方法
if (caller != null) {
caller.run();
}
}
在ZygoteServer构造中,回头根据参数isPrimaryZygote去创建主模式socket,还是辅模式socket的服务端:
@frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
if (isPrimaryZygote) {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
} else {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}
mUsapPoolSupported = true;
fetchUsapPoolPolicyProps();
}
可以看到,创建主模式的socket用的就是Zygote.PRIMARY_SOCKET_NAME,辅模式用的是Zygote.SECONDARY_SOCKET_NAME。这就与前面连接socket所用的name对应上了。
因为zygote的启动脚本有好几种,采用的是init.zygote32_64这类型的脚本,则name为Zygote.PRIMARY_SOCKET_NAME,如果采用的是zygote_secondary,则name为Zygote.SECONDARY_SOCKET_NAME。
因此AMS是通过socket连接通知zygote需要创建进程,中间根据不同的模式连接不同的socket,将应用启动参数传递进行通信。
Zygote收到请求并创建应用程序进程
在上面socket连接成功并匹配ABI后会返回一个ZygoteState类型对象,然后会将应用进程启动参数写入这个ZygoteState对象中去,这样zygote进程就会通过socket收到创建应用程序进程的请求参数。
那zygote是如何接收参数的呢?在ZygoteInit中创建了ZygoteServer对象后,会进入他的runSelectLoop方法:
@frameworks/base/core/java/com/android/internal/os/ZygoteServer.java#152
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
* @param abiList list of ABIs supported by this zygote.
*/
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> peers = new ArrayList<>();
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
while (true) {
if (pollReturnValue == 0) {
// The poll returned zero results either when the timeout value has been exceeded
// or when a non-blocking poll is issued and no FDs are ready. In either case it
// is time to refill the pool. This will result in a duplicate assignment when
// the non-blocking poll returns zero results, but it avoids an additional
// conditional in the else branch.
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;
} else {
boolean usapPoolFDRead = false;
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
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 {
//2
ZygoteConnection connection = peers.get(pollIndex);
boolean multipleForksOK = !isUsapPoolEnabled()
&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();
final Runnable command =
connection.processCommand(this, multipleForksOK);
...
return command;
}
...
} else {
...
}
}
...
}
...
}
}
当有AMS请求来的时候,会调用注释2的代码,通过调用ZygoteConnection的processCommand方法去处理请求的数据:
@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);
try {
if (pid == 0) {
//当前代码逻辑在子进程中
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//处理应用程序进程
return handleChildProc(parsedArgs, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
...
}
}
...
}
首先会去获取应用程序进程的启动参数,然后调用Zygote的forkAndSpecialize函数创建应用程序进程。forkAndSpecialize主要是通过fork当前进程来创建一个子进程,如果返回值pid为0,则表示当前代码逻辑在新创建的子进程中,这个时候就回去调用handleChildProc方法去处理应用程序进程:
@frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java#handleChildProc
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
/*
* By the time we get here, the native code has closed the two actual Zygote
* socket connections, and substituted /dev/null in their place. The LocalSocket
* objects still need to be closed properly.
*/
closeSocket();
Zygote.setAppProcessName(parsedArgs, TAG);
// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.mInvokeWith != null) {
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.mRemainingArgs);
// Should not get here.
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
//在子进程中,isZygote为false
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(
parsedArgs.mRemainingArgs /* classLoader */);
}
}
}
当前进程处于子进程中,因此isZygote必为false,逻辑进入到ZygoteInit的zygoteInit函数中:
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#zygoteInit
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
RuntimeInit.commonInit();
//1.启动Binder线程池
ZygoteInit.nativeZygoteInit();
//2.返回Runnable,被调用run方法后进入入口类的main方法
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
private static native void nativeZygoteInit();
注释1处会在新创建的应用程序进程中创建Binder线程池,注释2则会调用RuntimeInit的applicationInit方法:
@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#applicationInit
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
其中args.startClass的值就是上文提到的android.app.ActivityThread,继续到findStaticMain方法:
@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#findStaticMain
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//1.反射获取对象
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
//得到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.
*/
return new MethodAndArgsCaller(m, argv);
}
通过反射找到android.app.ActivityThread的main方法,然后将参数与方法封装为一个MethodAndArgsCaller类型的Runnable对象返回,供前文去调用run方法,从而执行到ActivityThread的main方法中去。到这里,应用程序进程就创建完成并且运行了主线程的管理类AvtivityThread。
zygote创建的所有进程(应用程序进程和SystemServer进程),都是fork处进程后,在子进程中进入ZygoteInit的静态方法zygoteInit处理进程后续工作:首先创建Binde线程池,目的是为了方便与其他进程进行通信;其次是通过传入的参数,利用反射技术进入到其main函数(应用程序进程的入口是android.app.ActivityThread,SystmeServer的入口是com.android.server.SystemServer)