应用程序程序进程的启动可以分为两大步,分别是AMS发送启动应用程序进程请求和Zygote接收请求并创建应用程序,首先来看第一步
时序图如下

- 获取要创建的应用程序进程的用户ID(uid)
- 创建用户组ID(gids)并赋值
- 指定应用程序进程主线程的类名为android.app.ActivityThread
- 调用Process.start方法来启动应用程序
Process的start方法直接调用了ZygoteProcess中的start方法,这个ZygoteProcess类则是保持了与Zygote进程的通信状态,他负责与Zygote的socket建立连接并且开启进程(android.os.process)。我们接着看这个类的start方法,它在类中只是调用了这个类的startViaZygote方法,这个方法其实就是构建应用程序的启动参数并且调用该类中的zygoteSendArgsAndGetResult方法,而这个方法的参数又是通过openZygoteSocketIfNeeded提供。这个open方法实际上就是与ZygoteSocket建立连接,然后将参数封装到ZygoteState中,从而在zygoteSendArgsAndGetResult方法中利用构造的参数与socket通信。至此上半场就介绍完了,下半场则是从在Zygote中创建这个进程
下半场的时序图如下

- 获取并封装应用程序进程的启动参数
- 通过forkAndSpecialize创建当前进程的子进程并返回pid,这里的pid为0,
- 调用handleChildProc来处理应用程序进程
handleChildProc:这个方法其实就是为子进程做一些前置设置,比如关闭socket连接,创建binder连接池等。它主要做了两件事
- closeSocket
- 调用ZygoteInit中的zygoteInit方法
ZygoteInit.zygoteInit:它主要做了两件事
- 利用zygoteNativeInit方法创建binder连接池
- 调用RuntimeInit中的applicationInit
RuntimeInit.applicationInit:这个方法其实就构造了需要的参数Arguments,并且调用了findStaticMain(9.0)
findStaticMain:这里会通过反射找到需要执行的类及类中的main方法,这里的类则是在上半场传入的android.app.ActivityThread类,然后将参数和类传递给MethodAndArgsCaller,这个caller就是runnable,在他的run方法中执行传入的类及方法的method.invoke方法。 在9.0的源码中上半场的runSelectLoop是返回一个runnable的,也就是刚才最后的那个MethodAndArgsCaller,在ZygoteInit.java的main方法的最后则会调用这个runnable的run方法,至此新的应用程序进程已经启动,并且新进程的主线程ActivityThread也已经启动完成。
具体流程如下,它与非根activity的启动区别在startSpecificActivityLocked()方法中
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
getLaunchTimeTracker().setLaunchTime(r);
if (app != null && app.thread != null) {
...
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
在这个方法中首先会获取包含要启动activity的进程信息的ProcessRecord,新启动应用的话,这个值为null,所以启动根activity的话会调用这里的ActivityManagerService中的startProcessLocked这时候如果是方法,而启动非根activity会调用realStartActivityLocked方法。注意这里的字段“activity”它的变量名为hostingType,其中isolated值为false

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
// 解释1
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
...
} else {
app = null;
}
...
// 解释2
String hostingNameStr = hostingName != null
? hostingName.flattenToShortString() : null;
if (app == null) {
...
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, "startProcess: added package to existing proc");
}
...
checkTime(startTime, "startProcess: stepping in to startProcess");
// 解释3
final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
checkTime(startTime, "startProcess: done starting proc!");
return success ? app : null;
}
这里的解释1:很好理解因为上面传递的参数为false,所以会用getProcessRecordLocked来获取一个ProcessRecord对象。然后会处理一下这个hostingType,然后会调用解释3处的startProcessLocked方法,并且传入构造好的参数,我们继续看
private final boolean startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
...
try {
try {
final int userId = UserHandle.getUserId(app.uid);
AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
int[] permGids = null;
try {
checkTime(startTime, "startProcess: getting gids from package manager");
final IPackageManager pm = AppGlobals.getPackageManager();
permGids = pm.getPackageGids(app.info.packageName,
MATCH_DEBUG_TRIAGED_MISSING, app.userId);
StorageManagerInternal storageManagerInternal = LocalServices.getService(
StorageManagerInternal.class);
mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
app.info.packageName);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
/*
* Add shared application and profile GIDs so applications can share some
* resources like shared libraries and access user-wide resources
*/
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));
// Replace any invalid GIDs
if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
}
checkTime(startTime, "startProcess: building args");
...
final String seInfo = app.info.seInfo
+ (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
//解释1
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
} catch (RuntimeException e) {
...
}
}
可以看到这里其实就是进一步的构造创建进程所需要的参数比如gids等,这里需要注意的是解释1处传递的entryPoint,它是“android.app.ActivityThread”,我们继续跟踪代码
private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
app.pendingStart = true;
app.killedByAm = false;
app.removed = false;
app.killed = false;
final long startSeq = app.startSeq = ++mProcStartSeqCounter;
app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
//解释1
if (mConstants.FLAG_PROCESS_START_ASYNC) {
if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
"Posting procStart msg for " + app.toShortString());
mProcStartHandler.post(() -> {
try {
synchronized (ActivityManagerService.this) {
final String reason = isProcStartValidLocked(app, startSeq);
if (reason != null) {
Slog.w(TAG_PROCESSES, app + " not valid anymore,"
+ " don't start process, " + reason);
app.pendingStart = false;
return;
}
app.usingWrapper = invokeWith != null
|| SystemProperties.get("wrap." + app.processName) != null;
mPendingStarts.put(startSeq, app);
}
//解释2
final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
requiredAbi, instructionSet, invokeWith, app.startTime);
synchronized (ActivityManagerService.this) {
handleProcessStartedLocked(app, startResult, startSeq);
}
}
...
});
return true;
} else {
...
}
}
这里其实最重要就两个地方,解释1处的常量默认为true所以不会走else分支,最后会调用解释2处的startProcess方法来启动进程
private ProcessStartResult startProcess(String hostingType, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
final ProcessStartResult startResult;
//解释1
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
//解释2
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkTime(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
这里的解释1就是根据hostingType来判断执行的方法,因为我们之前说过传的是“activity”,虽然在中途进行过修改,但肯定不是“webview_service”,所以这里会执行else中的逻辑,也就是调用Process.start方法,这是android.os.Process中的方法
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
需要注意的是这里的第一个参数processClass,它是被用作进程主入口的class,上一步传来的值为entryPoint,就是“android.app.ActivityThread”。这里调用的是zygoteProcess的start方法,而这个zygoteProcess是定义在Process类中的静态常量,其定义如下
/**
* @hide for internal use only.
*/
public static final String ZYGOTE_SOCKET = "zygote";
/**
* @hide for internal use only.
*/
public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary";
public static final ZygoteProcess zygoteProcess =
new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);
这个ZygoteProcess是用来维持与Zygote进程进行通信状态的。我们看看它的构造方法做了什么
/**
* The name of the socket used to communicate with the primary zygote.
*/
private final LocalSocketAddress mSocket;
/**
* The name of the secondary (alternate ABI) zygote socket.
*/
private final LocalSocketAddress mSecondarySocket;
public ZygoteProcess(String primarySocket, String secondarySocket) {
this(new LocalSocketAddress(primarySocket, LocalSocketAddress.Namespace.RESERVED),
new LocalSocketAddress(secondarySocket, LocalSocketAddress.Namespace.RESERVED));
}
public ZygoteProcess(LocalSocketAddress primarySocket, LocalSocketAddress secondarySocket) {
mSocket = primarySocket;
mSecondarySocket = secondarySocket;
}
可以看到就是创建了两个socket,一个名字为“zygote”,一个名为“zygote_secondary”。我们继续往下看这个start方法
public final Process.ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
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方法
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
boolean startChildZygote,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --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_READ) {
argsForZygote.add("--mount-external-read");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
argsForZygote.add("--mount-external-write");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
// --setgroups is a comma-separated list
if (gids != null && gids.length > 0) {
StringBuilder sb = new StringBuilder();
sb.append("--setgroups=");
int sz = gids.length;
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(',');
}
sb.append(gids[i]);
}
argsForZygote.add(sb.toString());
}
if (niceName != null) {
argsForZygote.add("--nice-name=" + niceName);
}
if (seInfo != null) {
argsForZygote.add("--seinfo=" + seInfo);
}
if (instructionSet != null) {
argsForZygote.add("--instruction-set=" + instructionSet);
}
if (appDataDir != null) {
argsForZygote.add("--app-data-dir=" + appDataDir);
}
if (invokeWith != null) {
argsForZygote.add("--invoke-with");
argsForZygote.add(invokeWith);
}
if (startChildZygote) {
argsForZygote.add("--start-child-zygote");
}
argsForZygote.add(processClass);
if (extraArgs != null) {
for (String arg : extraArgs) {
argsForZygote.add(arg);
}
}
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
这里首先会构造创建进程的参数比如"--setuid--"等,然后会调用zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);方法,这个方法中又包含了openZygoteSocketIfNeeded(abi)方法,我们首先看这个方法
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
// 注释1
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
}
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
这里的primaryZygoteState则代表的是与值为“zygote”的socket建立连接后的状态信息,所以注释1则是通过connect方法来建立与Zygote进程中的socket进行连接。如果primaryZygoteState与应用程序进程所需的ABI不匹配才会使用secondary。这里就不介绍了。接着看zygoteSendArgsAndGetResult方法
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
// Throw early if any of the arguments are malformed. This means we can
// avoid writing a partial response to the zygote.
int sz = args.size();
for (int i = 0; i < sz; i++) {
if (args.get(i).indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx("embedded newlines not allowed");
}
}
/**
* See com.android.internal.os.SystemZygoteInit.readArgumentList()
* Presently the wire format to the zygote process is:
* a) a count of arguments (argc, in essence)
* b) a number of newline-separated argument strings equal to count
*
* After the zygote process reads these it will write the pid of
* the child or -1 on failure, followed by boolean to
* indicate whether a wrapper process was used.
*/
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
// Should there be a timeout on this?
Process.ProcessStartResult result = new Process.ProcessStartResult();
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
其实就是将argsForZygote参数写入ZygoteState中,并且把这个state写入socket中,至此向Zygote发送请求的过程就结束了,我们继续看zygote接收到请求的过程。 这个过程则是在ZygoteInit中的main方法中的runSelectLoop方法实现的,因为在main方法中创建了一个名为“zygote”的socket。
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
// 解释1
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
..
return command;
} ...
}
当有AMS发送请求时应为这里的fds肯定不为0,所以代码会执行到解释1处。这里会取出这个connection并且调用它的processOneCommand方法
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
applyInvokeWithSystemProperty(parsedArgs);
...
fd = zygoteServer.getServerSocketFileDescriptor();
if (fd != null) {
fdsToClose[1] = fd.getInt$();
}
fd = null;
// 解释1
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
// 解释2
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} 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);
}
}
这里首先会构造一些参数,比如开头的applyInvokeWithSystemProperty会将invokeWith参数置为null。然后调用解释1处的forkAndSpecialize方法来创建一个子进程,如果创建成功的话则其pid为0,并且关闭此次socket连接。接着调用handleChildProc方法(运行在新的进程及应用程序进程中)
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.invokeWith != null) {
...
} else {
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
}
这里的invokeWith为null所以会执行else中的逻辑,而且isZygote也为false(之前构造创建进程的args),所以为执行zygoteInit方法,这之后就跟Zygote启动时这个方法的后续调用流程是一样的,只不过这里最终调用的是android.app.ActivityThread中的main方法。我们来看看这个main方法
public static void main(String[] args) {
...
Process.setArgV0("<pre-initialized>");
// 解释1
Looper.prepareMainLooper();
...
// 解释2
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
// 解释3
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();
...
}
可以看到其实就是做了四件事,解释1处的创建主线程的Looper,解释2处的创建ActivityThread类,解释3处的创建主线程handler,最后loop方法开始工作。我们刚才明明是启动一个activity,但是这里却新建了一个进程,那么activity在哪儿启动的呢,我们接着看这里被忽视的方法attach方法,我们来看看他是做什么的。
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
...
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 解释1
final IActivityManager mgr = ActivityManager.getService();
try {
// 解释2
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...
}
...
}
我们上一步中传递过来的system参数为false。所以这里会执行if中的语句,并且在解释1处获取了ActivityManagerService,在解释2处调用它的attachApplication方法,我们就接着看看这个方法
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
其实就是接着调用 attachApplicationLocked(thread, callingPid, callingUid, startSeq)方法
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
return true;
}
这里的模式为normal,所以会执行if中的mStackSupervisor.attachApplicationLocked方法
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getChildAt(stackNdx);
if (!isFocusedStack(stack)) {
continue;
}
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.uid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
//解释1
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}
其实这里只看解释1处的代码就能明白,它调用了realStartActivityLocked方法,这就与开篇分析的启动非根activity(进程未创建)与根activity的区别不谋而合了。这里进程已经启动了,所以就跟非根activity的启动一样调用了realStartActivityLocked方法,当然之后的逻辑也一样,这里就不在赘述了。