应用程序进程启动过程
想要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经启动。AMS在启动应用程序时会检查这个应用程序所需要的应用程序进程是否已经存在,如果不存在就会请求Zygote进程启动需要的应用程序进程。在Zygote进程启动过程中可以知道,在方法中会创建一个Server端的Socket用来等待AMS请求Zygote进程创建子进程。Zygote进程通过fork自身创建子进程,这样,子进程就会获得
1 应用程序进程简介
想要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经启动。 AMS
在启动应用程序时会检查这个应用程序所需要的应用程序进程是否已经存在,如果不存在就会请求 Zygote
进程启动需要的应用程序进程。 在 Zygote进程启动过程 中可以知道,在 ZygoteInit.main
方法中会创建一个 Server
端的 Socket
用来等待 AMS
请求 Zygote
进程创建子进程。Zygote
进程通过 fork
自身创建子进程,这样,子进程就会获得 Zygote
进程在启动时创建的 Java
虚拟机实例。
在应用程序的创建过程中,除了获取 Java
虚拟机的实例外,还创建了 Binder
线程池和消息循环,这样运行应用进程中的应用程序就可以使用 Binder
进行进程间通信以及处理消息了。
2 应用程序进程启动过程
应用程序进程创建的过程比较复杂,这里分为两部分, AMS
发送启动应用程序进程请求和 Zygote
接收请求并创建应用程序进程。
2.1 AMS
发送启动应用程序进程请求
以下是相关时序图:
ActivityManagerServive
如果想要启动应用程序进程,就需要向 Zygote
进程发送创建应用程序进程的请求。AMS
是通过调用 ActivityManagerService.LocalService.startProcess
方法向 Zygote
进程发送请求的,代码如下所示:
// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class LocalService extends ActivityManagerInternal {
@Override
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, 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) {
startProcessLocked(processName, info, knownToBeDead,
0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */,
false /* isolated */,
true /* keepIfLarge */); // 1
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info,
boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord,
boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead,
intentFlags,
hostingRecord, allowWhileBooting,
isolated, 0 /* isolatedUid */,
keepIfLarge,
null /* ABI override */,
null /* entryPoint */,
null /* entryPointArgs */,
null /* crashHandler */); // 2
}
}
在注释 2
处调用 ProcessList.startProcessLocked
方法,如下所示:
// /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord,
boolean allowWhileBooting, boolean isolated,
int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint,
String[] entryPointArgs, Runnable crashHandler) {
...
final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
...
}
@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
String abiOverride) {
return startProcessLocked(app, hostingRecord, false /* disableHiddenApiChecks */,
false /* mountExtStorageFull */, abiOverride);
}
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
boolean disableHiddenApiChecks, boolean mountExtStorageFull,
String abiOverride) {
...
int uid = app.uid; // 1 获取要创建的应用程序进程的用户 ID
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
...
// 2. 对 gids 进行创建和赋值
if (ArrayUtils.isEmpty(permGids)) {
gids = new int[3];
} else {
gids = new int[permGids.length + 3];
System.arraycopy(permGids, 0, gids, 3, permGids.length);
}
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
...
final String entryPoint = "android.app.ActivityThread"; // 3
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, runtimeFlags,
mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
}
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags,
int mountExternal, String seInfo, String requiredAbi,
String instructionSet, String invokeWith, long startTime) {
...
final Process.ProcessStartResult startResult = startProcess(hostingRecord, entryPoint, app,
uid, gids, runtimeFlags,
mountExternal, seInfo,
requiredAbi, instructionSet,
invokeWith, startTime);
...
}
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids,
int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi,
String instructionSet, String invokeWith,
long startTime) {
...
// 4 启动应用程序进程
startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags,
mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi,
instructionSet, app.info.dataDir, invokeWith,
app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
...
}
在注释 1
处得到要创建的进程的用户 ID
,在注释 2
处对用户组 ID
(gids
) 进行创建和赋值。在注释 3
处将 entryPoint
赋值为 android.app.ActivityThread
,这个值就是应用程序进程主线程的类名。 在注释 4
处调用 Process.start
方法,将此前得到的进程的用户 ID
和用户组 ID
传进去。继续看 Process.start
方法:
// /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,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
/*useUsapPool=*/ true, zygoteArgs); // 1
}
在 Process.start
方法中调用了 ZygoteProcess.start
方法,其中,ZygoteProcess
类用于保持与 Zygote
进程的通信状态,ZygoteProcess.start
方法如下所示:
// /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,
boolean useUsapPool,
@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, useUsapPool, zygoteArgs); // 1
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG, "Starting VM process through Zygote failed");
throw new RuntimeException("Starting VM process through Zygote failed", ex);
}
}
在注释 1
处调用了 ZygoteProcess.startViaZygote
方法,代码如下所示:
// /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,
boolean useUsapPool,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
// 1 创建字符串列表 argsForZygote,并将应用进程的启动参数保存在 argForZygote 中
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);
...
synchronized(mLock) {
// 2
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), // 3
useUsapPool, argsForZygote);
}
}
在注释 1
处创建了字符串列表 argsForZygote
,并将启动应用程序进程的启动参数保存在 argsForZygote
中,方法最终会调用 ZygoteProcess.zygoteSendArgsAndGetResult
方法,需要注意的是,ZygoteProcess.zygoteSendArgsAndGetResult
的第一个参数是 ZygoteProcess.openZygoteSocketIfNeeded
方法。ZygoteProcess.zygoteSendArgsAndGetResult
方法如下所示:
// /frameworks/base/core/java/android/os/ZygoteProcess.java
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
for (String arg : args) {
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 (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
try {
return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
} catch (IOException ex) {
Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
+ ex.getMessage());
}
}
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); // 1
}
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter; // 2
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);
}
}
ZygoteProcess.zygoteSendArgsAndGetResult
方法的主要作用就是将传入的引用进程的启动参数 args
写入到 ZygoteState
中。ZygoteState
是 ZygoteProcess
的镜头内部类,用于表示与 Zygote
进程的通信状态,ZygoteState
是由 ZygoteProcess.openZygoteSocketIfNeeded
方法返回的,以下是 ZygoteProcess.openZygoteSocketIfNeeded
方法的代码:
// /frameworks/base/core/java/android/os/ZygoteProcess.java
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
// 尝试与 Zygote 进程建立连接
attemptConnectionToPrimaryZygote(); // 1
// 连接 Zygote 主模式返回的 ZygoteState 是否与启动应用程序进程所需要的 ABI 匹配
if (primaryZygoteState.matches(abi)) { // 2
return primaryZygoteState;
}
if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary. 如果不匹配,则尝试连接 Zygote 辅模式
attemptConnectionToSecondaryZygote(); // 3
// 连接 Zygote 辅模式返回的 ZygoteState 是否与启动因公程序进程所需要的 ABI 匹配
if (secondaryZygoteState.matches(abi)) { // 4
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
/**
* 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()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress); // 5
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
maybeSetHiddenApiAccessStatslogSampleRate(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()) {
secondaryZygoteState =
ZygoteState.connect(mZygoteSecondarySocketAddress, mUsapPoolSecondarySocketAddress); // 6
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
maybeSetHiddenApiAccessStatslogSampleRate(secondaryZygoteState);
}
}
在 Zygote
进程启动的过程中,会在 Zygote.main
方法中创建 name
为 zygote
的 Server
端的 Socket
。在注释 5
处会调用 ZygoteState.connect
方法与名称为 PRIMARY_SOCKET_NAME
的 Socket
建立连接并返回 ZygoteState
类型的变量 primaryZygoteState
对象,PRIMARY_SOCKET_NAME
的值为 zygote
。在注释 3
处,如果 primaryZygoteState
与启动应用用程序进程所需的 ABI
不匹配,则会在注释 6
处连接 name
为 zygote_secondary
的 Socket
。如果这两种模式都不匹配则抛出异常。
Zygote
的启动脚本有 4
种,如果采用的是 init.zygote32_64.rc
或者 init.zygote64_32.rc
,则 name
为 zygote
为主模式,name
为 zygote_secondary
为辅模式。
// frameworks/base/core/java/com/android/internal/os/Zygote.java
public static final String PRIMARY_SOCKET_NAME = "zygote";
public static final String SECONDARY_SOCKET_NAME = "zygote_secondary";
public static final String USAP_POOL_PRIMARY_SOCKET_NAME = "usap_pool_primary";
public static final String USAP_POOL_SECONDARY_SOCKET_NAME = "usap_pool_secondary";
// /frameworks/base/core/java/android/os/ZygoteProcess.java
public ZygoteProcess() {
mZygoteSocketAddress =
new LocalSocketAddress(Zygote.PRIMARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
mZygoteSecondarySocketAddress =
new LocalSocketAddress(Zygote.SECONDARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
mUsapPoolSocketAddress =
new LocalSocketAddress(Zygote.USAP_POOL_PRIMARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
mUsapPoolSecondarySocketAddress =
new LocalSocketAddress(Zygote.USAP_POOL_SECONDARY_SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
}
2.2 Zygote
接收请求并创建应用程序进程
Zygote
接收到请求并创建应用程序进程的时序图如下所示:
Socket
连接成功并匹配 ABI
之后会返回 ZygoteState
类型对象,在 ZygoteProcess.zygoteSendArgsAndGetResult
方法中,会将应用程序进程的启动参数写入到 ZygoteState
中,这样,Zygote
进程就会收到一个创建新的应用程序进程的请求。以下是 ZygoteInit.main
方法的代码:
// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
...
Runnable caller;
try {
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
// 预加载类和资源
preload(bootTimingsTraceLog); // 1
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
// 创建一个 Server 端的 Socket
zygoteServer = new ZygoteServer(isPrimaryZygote); // 2
if (startSystemServer) {
// 启动 system_server 进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // 3
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// 等待 AMS 请求
caller = zygoteServer.runSelectLoop(abiList); // 4
}catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
if (caller != null) {
caller.run();
}
}
注释 1
处为预加载资源。注释 2
处创建了一个 Server
端的 Socket
,这个 name
为 zygote
的 Socket
用来等待 AMS
来请求 Zygote
,以创建新的应用程序进程。注释 3
处为启动 system_server
进程,这样系统服务也就由 system_server
进程启动起来。在注释 4
处调用 ZygoteServer.runSelectLoop
方法来等待 AMS
请求创建新的应用程序进程。以下是 ZygoteServer.runSelectLoop
方法:
// /frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); // 1
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
while (true) {
...
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 {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this); // 2
// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
if (command != null) {
throw new IllegalStateException("command != null");
}
...
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);
}
}
} catch (Exception e) {
...
}
}
...
}
...
}
}
当有 AMS
的请求数据到来时,会调用注释 2
处的代码,也就是 ZygoteConnection.processOneCommand
方法来处理请求数据的:
// /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
ZygoteArguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = Zygote.readArgumentList(mSocketReader); // 1 获取应用程序进程的启动参数
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
...
int pid = -1;
...
parsedArgs = new ZygoteArguments(args); // 2
...
// 3 创建应用程序进程
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.mTargetSdkVersion);
try {
// 当前代码运行在子进程中
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
// 处理应用程序进程
return handleChildProc(parsedArgs, descriptors, 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, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
在注释 1
处调用 Zygote.readArgumentList
方法来获取应用程序进程的启动参数,并在注释 2
处将返回的字符串数组 args
封装到 ZygoteArguments
类型的 parsedArgs
对象中。在注释 3
处调用 Zygote.forkAndSpecialize
方法来创建应用程序进程,参数为 parsedArgs
中存储的应用进程启动参数,返回值为 pid
。Zygote.forkAndSpecialize
方法主要是通过 fork
当前进程来创建一个子进程的,如果 pid == 0
,则说明当前代码的逻辑运行在新创建的子进程(应用程序进程)中,这是就会调用 ZygoteConnection.handleChildProc
方法来处理应用程序进程, 代码如下所示:
// /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
closeSocket();
...
// 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) {
// 1
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs,
null /* classLoader */);
}
}
}
在 ZygoteConnection.handleChildProc
方法中调用了 ZygoteInit.zygoteInit
方法,如下所示:
// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, 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(); // 1
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); // 2
}
在注释 1
处会在新创建的应用程序进程中创建 Binder
线程池(下面会做详细介绍),在注释 2
处调用了 RuntimeInit.applicationInit
方法:
// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
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); // 1
}
RuntimeInit.applicationInit
方法会在注释 1
处调用 RuntimeInit.findStaticMain
方法,需要注意的是,第一个参数 arg.startClass
,它指的就是 android.app.ActivityThread
。 接下来查看 RuntimeInit.findStaticMain
方法:
// /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) {
throw new RuntimeException( "Missing class when invoking static main " + className, ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class }); // 2
} 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);
}
...
/*
* 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); // 3
}
在注释 1
处通过反射获得了 android.app.ActivityThread
类,接下来在注释 2
处获得了 ActivityThrea.main
方法,并将 ActivityThread.main
方法传入注释 3
处的 RuntimeInit
中的 MethodAndArgsCaller
类:
// /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) {
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);
}
}
}
注释 1
处的 mMethod
指的是 ActivityThread.main
方法,调用了 mMethod.invoke
方法后,ActivityThread.maim
方法就会被动态调用了,应用程序进程就进入了 ActivityThread.main
方法中。
在 ZygoteInit.main
方法中调用 MethodAndArgsCaller.run
方法:
// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
Runnable caller;
...
caller = zygoteServer.runSelectLoop(abiList);
...
if (caller != null) {
caller.run();
}
}
3 Binder
线程池启动过程
在 ZygoteInit.zygoteInit
方法中会启动 Binder
线程池:
// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, 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(); // 1
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
private static final native void nativeZygoteInit(); // 2
nativeZygoteInit
方法是一个 JNI
方法,它对应的是 AndroidRuntime.cpp
的 JNINativeMethod
数组中的 register_com_android_internal_os_ZygoteInit_nativeZygoteInit
,对应的函数是 com_android_internal_os_ZygoteInit_nativeZygoteInit
:
// /frameworks/base/core/jni/AndroidRuntime.cpp
static const RegJNIRec gRegJNI[] = {
...
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
...
}
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};
return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
methods, NELEM(methods));
}
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit(); // 1
}
gCurRuntime
是 AndroidRuntime
类型的指针,它是在 AndroidRuntime
初始化的时候创建的:
// /frameworks/base/core/jni/AndroidRuntime.cpp
static AndroidRuntime* gCurRuntime = NULL;
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
SkGraphics::Init();
// Pre-allocate enough space to hold a fair number of options.
mOptions.setCapacity(20);
assert(gCurRuntime == NULL); // one per process
gCurRuntime = this;
}
AppRuntiem
继承自 AndroidRuntime
,AppRuntime
创建时会调用 AndroidRuntime
的构造函数,gCurRuntime
就会被初始化,它指向的是 AppRuntime
。接下来查看 AppRuntime.onZygoteInit
函数,AppRuntime
在 app_main.cpp
中实现:
// /frameworks/base/cmds/app_process/app_main.cpp
class AppRuntime : public AndroidRuntime
{
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();// 1
}
}
注释 1
处调用了 ProcessState.startThreadPool
函数来启动 Binder
线程池:
// /frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) { // 1
mThreadPoolStarted = true; // 2
spawnPooledThread(true);
}
}
支持 Binder
通信的进程中都有一个 ProcessState
类,它里面有一个 mThreadPoolStarted
变量,用来表示 Binder
线程池是否已经被启动过,默认值是 false
,在每次调用 startThreadPool
函数时都会在注释 1
处先检查这个标记,从而确保 Binder
线程池只会启动一次。如果 Binder
线程池未被启动,则在注释 2
处设置 mThreadPoolStarted = true
,并调用 spawnPooledThread
函数来创建线程池中的第一个线程,也就是线程池的主线程:
// /frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string()); // 1
}
}
可以看到 Binder
线程为一个 PoolThread
。在注释 1
调用 PoolThread.run
函数来启动一个新的线程,下面是 PoolThread
的相关代码:
// /frameworks/native/libs/binder/ProcessState.cpp
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain); // 1
return false;
}
const bool mIsMain;
};
PoolThread
继承了 Thread
类,在注释 1
处调用了 IPCThreadState
的 joinThreadPool
函数,将当前线程注册到 Binder
驱动中,这样创建的线程就加入了 Binder
线程池中,这样,新创建的应用程序进程就支持 Binder
进程间通信。 我们只需要创建当前进程的 Binder
对象,并将它注册到 ServiceManager
中就可以实现 Binder
进程间通信,而不必关系进程间是如何通过 Binder
进行通信的。
4 消息循环创建过程
通过上面的介绍可以知道,在 ZygoteInit.main
中调用 caller.run
,会执行 MethodAndArgsCaller.run
方法:
// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
Runnable caller;
...
caller = zygoteServer.runSelectLoop(abiList);
...
if (caller != null) {
caller.run();
}
}
以下是 MethodAndArgsCaller
的相关源码:
// /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) {
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);
}
}
}
而注释 1
处的 mMethod
指的是 ActivityThread.main
方法,以下是 ActivityThread.main
的相关源码:
// /frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
...
Looper.prepareMainLooper(); // 1 创建主线程 Looper
ActivityThread thread = new ActivityThread(); // 2
thread.attach(false, startSeq);
if (sMainThreadHandler == null) { // 3
sMainThreadHandler = thread.getHandler(); // 4 创建主线程的 H 类
}
if (false) {
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop(); // 5 Looper 开始工作
}
ActivityThread
类用于管理当前应用程序进程的主线程,在注释 1
处创建主线程的消息循环 Looper
,在注释 2
处创建 ActivityThread
。在注释 3
出判断 Handler
类型的 sMainThreadHandler
是否为 null
,如果为 null
则在注释 4
出获取 H
类并赋值给 sMainThreadHandler
,这个 H
继承自 Handler
,是 ActivityThread
的内部类,用户处理主线程的消息循环。注释 5
处调用 Looper.loop
方法,使得 Looper
开始处理消息。
可以看出,系统在应用程序进程启动完成后,会创建一个消息循环,这样运行在应用程序进程中的应用程序就可以方便的使用消息处理机制。
更多推荐
所有评论(0)