前言
Activity 启动过程文章系列中,首先会先对启动流程从头到尾进行简要梳理,后续文章会对其中重要细节进行详细展开。
启动流程梳理:
- Activity 启动流程(一)—— Launcher 阶段
- Activity 启动流程(二)—— AMS 处理阶段
- Activity 启动流程(三)—— 应用程序进程启动阶段
- Activity 启动流程(四)—— ActivityThread 初始化阶段
- Activity 启动流程(五)—— Activity 启动阶段
在 Launcher 桌面点击 icon 启动一个应用的组件如 Activity 时,AMS 在启动应用程序时会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求 zygote 进程启动所需要的应用程序进程。
下面详细介绍一下应用程序进程启动过程。
1. AMS 发送启动应用程序进程请求
点击 icon 时,如应用程序进程未启动,会通过 AMS 的 startProcess 方法启动应用程序进程:
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
// If the process is known as top app, set a hint so when the process is
// started, the top priority can be applied immediately to avoid cpu being
// preempted by other processes before attaching the process of top app.
final long startTimeNs = SystemClock.elapsedRealtimeNanos();
HostingRecord hostingRecord =
new HostingRecord(hostingType, hostingName, isTop);
ProcessRecord rec = getProcessRecordLocked(processName, info.uid);
ProcessRecord app = startProcessLocked(processName, info, knownToBeDead,
0 /* intentFlags */, hostingRecord,
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
接着会调用 startProcessLocked 方法:
// services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
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 */,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
接着调用 ProcessList 的 startProcessLocked 方法,进程启动成功会返回 true:
// frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
String abiOverride) {
...
try {
...
// ProcessRecord 是一个描述进程的数据结构,记录着当前运行的进程的详细信息。
// 获取要创建的应用程序进程的用户ID
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
boolean externalStorageAccess = false;
if (!app.isolated) {
...
// 创建用户组 ID 并赋值
gids = computeGidsForProcess(mountExternal, uid, permGids, externalStorageAccess);
}
...
// 应用程序进程主线程类名
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
}
...
}
@GuardedBy("mService")
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 startTime) {
...
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
...
} else {
try {
// 启动应用程序进程
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
} catch (RuntimeException e) {
Slog.e(ActivityManagerService.TAG, "Failure starting process "
+ app.processName, e);
app.setPendingStart(false);
mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
false, false, true, false, false, app.userId, "start failure");
}
return app.getPid() > 0;
}
}
ProcessRecord 是一个描述进程的数据结构,记录着当前运行的进程的详细信息。
// 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;
boolean regularZygote = false;
if (hostingRecord.usesWebviewZygote()) {
...
} else if (hostingRecord.usesAppZygote()) {
...
} else {
regularZygote = true;
// 调用 Process 的 start 方法
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()});
}
...
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
调用 Process 的 start 方法:
// 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);
}
调用 ZygoteProcess 的 start 方法,ZygoteProcess 用于保持与 Zygote 进程的通信状态:
// 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) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
startViaZygote 方法通过 zygote 机制开启一个新的进程:
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 {
// 创建字符串列表 argsForZygote,并将应用进程的启动参数保存在 argsForZygote 中
ArrayList<String> argsForZygote = new ArrayList<>();
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
...
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
}
方法最后调用 zygoteSendArgsAndGetResult,向 Zygote 进程发送参数列表,启动一个新的子进程并返回子进程的 pid。:
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
...
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
zygoteSendArgsAndGetResult 方法主要作用是将传入的应用进程的启动参数 argsForZygote 写入 ZygoteState 中,ZygoteState 是 ZygoteProcess 的静态内部类,用于表示与Zygote 进程通信的状态。
调用 openZygoteSocketIfNeeded 方法,如果与 Zygote 进程的 Socket 连接未开启,则尝试开启,可能会产生阻塞和重试。连接调用的是 ZygoteState的connect 方法,ZygoteState 是 ZygoteProcess 的内部类。
该 ZygoteState 是如何创建的:
@GuardedBy("mLock")
// core/java/android/os/ZygoteProcess.java
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);
}
@GuardedBy("mLock")
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
maybeSetApiDenylistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
}
在 ZygoteInit 的 main 方法中创建了一个name 为 zygote 的 Server 端的 Socket。调用 ZygoteState 的 connect 方法与 primary zygote 的 Socket 进行连接,返回 ZygoteState 类型的 primaryZygoteState 对象。若 primaryZygoteState 与启动应用程序进程所需的 ABI 不匹配,则会连接 secondary zygote 的 Socket。
ZygoteProcess的attemptZygoteSendArgsAndGetResult()方法中使用ZygoteState中保存的BufferedWriter和DataInputStream来进行Socket通信,进行数据流的传输和读取,最后把pid和usingWrapper封装到ProcessStartResult中返回:
// 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);
}
}
2. Zygote 接收请求并创建应用程序进程
Socket 连接成功并匹配 ABI 后会返回 ZygoteState 类型对象。在 zygoteSendArgsAndGetResult 中已经将应用进程的启动参数 argsForZygote 写入 ZygoteState 中。这样 Zygote 进程就会收到一个创建新的应用程序进程的请求。
ZygoteInit 的 main 方法:
// com.android.internal.os.ZygoteInit
public static void main(String[] argv) {
...
try {
...
if (!enableLazyPreload) {
...
// 预加载类和资源
preload(bootTimingsTraceLog);
...
}
...
// 创建 ZygoteServer
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
// 启动 SystemServer 进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
...
}
...
// 死循环,类似 Looper.Loop() 等待 AMS 请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
...
} finally {
...
}
...
}
创建一个 Server 端的 Socket:
// core/java/com/android/internal/os/ZygoteServer.java
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
if (isPrimaryZygote) {// PRIMARY_SOCKET_NAME = "zygote"
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
} else {
// SECONDARY_SOCKET_NAME = "zygote_secondary"
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}
mUsapPoolSupported = true;
fetchUsapPoolPolicyProps();
}
这个 name 为 zygote 的 Socket 用来等待 AMS 请求 Zygote,以创建新的应用程序进程。
// core/java/com/android/internal/os/Zygote.java
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
int fileDesc;
// 拼接 Socket 的名称,ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_",socketName = "zygote"
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;// ANDROID_SOCKET_zygote
try {
// 得到 Socket 的环境变量的值
String env = System.getenv(fullSocketName);
// 将 Socket 环境变量的值转换为文件描述符的参数
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
}
try {
// 创建文件描述符
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
// 创建服务器端 Socket
return new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error building socket from file descriptor: " + fileDesc, ex);
}
}
Zygote 进程将 SystemServer 进程启动后,就会在在这个服务端的 Socket 上等待 AMS 请求 Zygote 进程来创建新的应用程序进程。
执行 runSelectLoop 等待 AMS 创建新的应用程序进程:
// core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> peers = new ArrayList<>();
// mZygoteSocket 为 createManagedSocketFromInitSocket 创建的服务端 Socket,获得该 Socket 的 fd 字段的值并添加到 fd 列表中
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
// 循环等待 AMS 请求 Zygote 进程创建新的应用程序
while (true) {
...
int pollReturnValue;
try {
// 处理轮询状态,当pollFDs有事件到来则往下执行,否则阻塞在这里
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
if (pollReturnValue == 0) {
...
} else {
boolean usapPoolFDRead = false;
// 序处理,即优先处理已建立连接的信息,后处理新建连接的请求
while (--pollIndex >= 0) {
// 采用I/O多路复用epoll机制,当接收到客户端请求到来,则往下执行;否则跳出本次循环
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) {
// pollIndex==0表示有新的客户端请求连接到来
// Zygote server socket
// 得到 ZygoteConnection 添加到 Socket 的连接列表 peers 中
ZygoteConnection newPeer = acceptCommandPeer(abiList);
// 加入到peers和fds, 即开始下一次监听
peers.add(newPeer);
// 将 ZygoteConnection 的 fd 添加到 socketFDs 中,以便可以接收到 AMS 发送过来的请求。
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {// pollIndex 不为 0
try {
// socket 连接成功之后从 Zygote 服务器的 socket 接受到的 Session socket
// 创建一个新的应用进程
ZygoteConnection connection = peers.get(pollIndex);
boolean multipleForksOK = !isUsapPoolEnabled()
&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();
final Runnable command =
connection.processCommand(this, multipleForksOK);
// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
...
return command;
} else {
...
}
} catch (Exception e) {
...
} finally {
...
}
} else {
...
}
}
...
}
...
}
}
当 AMS 的请求数据到来时,调用 ZygoteConnection 的 processCommand 方法:
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.
}
...
if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
|| !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
// 创建应用程序进程
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
// pid == 0 表示创建成功,则进入子进程中,即应用程序进程
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.
// pid < 0表示创建失败,则进入父进程返回消息给Client Socket表示启动失败
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
...
}
}
...
}
调用 Zygote 的 forkAndSpecialize 方法来创建应用程序进程,参数为 parsedArgs 中存储的应用进程启动参数,返回值为 pid。forkAndSpecialize 方法通过 fork 当前进程来创建一个子进程,如果 pid = 0,则说明当前代码逻辑运行在新创建的子进程(应用程序进程)中,这是会调用 handleParentProc 方法来处理应用程序进程:
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
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 {
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(
parsedArgs.mRemainingArgs /* classLoader */);
}
}
}
调用 ZygoteInit 的 zygoteInit 方法:
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
通过 nativeZygoteInit 方法在新创建的应用程序进程中创建 Binder 线程池。
接着调用 RuntimeInit 的 applicationInit 方法:
// core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
final Arguments args = new Arguments(argv);
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
findStaticMain 方法第一个参数 args.startClass 就是之前提到的 android.app.ActivityThread。
// core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
// 获取 android.app.ActivityThread 类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
// 获取 ActivityThread 类的 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);
}
最后通过 new MethodAndArgsCaller 抛出异常,这种抛出异常的处理会清除所有的设置过程需要的堆栈帧,并让 ActivityMain 方法看起来像是应用程序进程的入口方法。看一看 ZygoteInit.java 的 main 方法是如何捕获异常:
// com.android.internal.os.ZygoteInit
public static void main(String[] argv) {
...
try {
...
caller = zygoteServer.runSelectLoop(abiList);
}
...
if (caller != null) {
caller.run();
}
}
调用 MethodAndArgsCaller 的 run 方法:
// 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 });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
MethodAndArgsCaller 是 RuntimeInit 的静态内部类。通过 invoke 方法,ActivityThread 的 main 方法被调用。到这里,应用程序进程就创建完成了,并且运行了主线程的管理类 ActivityThread。
3. Binder 线程池启动过程
在应用程序进程创建过程中会启动 Binder 线程池。查看 ZygoteInit 的 zygoteInit 方法:
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
private static native void nativeZygoteInit();
通过 nativeZygoteInit 方法在新创建的应用程序进程中创建 Binder 线程池。nativeZygoteInit 是一个 JNI 方法。通过 AndroidRuntime.cpp 的 JNINativeMethod 数组中可知 nativeZygoteInit 对应的函数是 com_android_internal_os_ZygoteInit_nativeZygoteInit:
// core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
gCurRuntime 是 AndroidRuntime 类型的指针,它是在 AndroidRuntime 初始化时就创建的。AppRuntime 继承自 AndroidRuntime,AppRuntime 创建时就会调用 AndroidRuntime 的构造函数,gCurRuntime 就会被初始化,它指向的是 AppRuntime。查看 AppRuntime 的 onZygoteInit 函数,AppRuntime 在 app_main.cpp 中实现:
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
调用 startThreadPool 函数来启动 Binder 线程池:
// libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
支持 Binder 通信的进程中都有一个 ProcessState 类,它里面有一个 mThreadPoolStarted 变量,用来表示 Binder 线程池是否已经被启动过,默认值为 false。每次调用 startThreadPool 都会判断 Binder 线程池是否被启动。未启动就会调用 spawnPooledThread 函数来创建线程池中的第一个线程,也就是线程池的主线程;
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = sp<PoolThread>::make(isMain);
t->run(name.string());
}
}
Binder 线程为一个 PoolThread。通过 PoolThread 的 run 函数启动一个新线程。
查看 PoolThread 类中做了什么;
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
PoolThread 继承自 Thread 类。调用 IPCThreadState 的 joinThreadPool 函数,将当前线程注册到 Binder 驱动程序中,这样我们创建的线程就加入了 Binder 线程池中,新创建的应用程序进程进程就支持 Binder 进程间通信了。我们只需要创建当前进程的 Binder 对象,并将它注册到 ServiceManager 中就可以实现 Binder 进程间通信,而不必关心进程间是如何通过 Binder 进行通信的。