在前面我们从源码层面分析了Android系统启动流程,了解它们也主要是为了我们开发App服务的。应用程序想要启动首先需要应用程序进程存在,而应用程序进程的创建需要SystemServer进程中的ActivityManagerService向Zygote进程发送消息,通过zygote进程fork自身来创建应用程序进程,新创建的应用程序进程就有zygote进程创建的虚拟机实例,同时创建了Binder线程池和Handler消息循环机制,便于进程间消息通信。今天就来从源码角度分析我们关心的Android应用程序进程的启动流程。
应用程序进程的启动我们分为两个部分来分析
应用程序进程的创建是需要SystemServer进程中的ActivityManagerService向Zygote进程发送消息,进而由Zygote创建进程,然后启动应用程序进程,比如其中有一种AMS.startProcessLocked是在启动Activity时候,源码如下:
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
if (app != null && app.thread != null) {
try {
...
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
...
}
}
// 1
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
在此方法中先判断应用程序进程是都存在,不存在的话就需要进入到注释1的startProcessLocked中,下面我们通过源码进行分析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,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
@GuardedBy("this")
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) {
// 1
final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
requiredAbi, instructionSet, invokeWith, app.startTime);
}
}
上面注释1处调用了startProcess方法,其中有一个参数是是entryPoint, 追溯源码就会发现它是String entryPoint = "android.app.ActivityThread"
,接着进入内部查看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) {
/**启动一个进程*/
ProcessStartResult 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});
}
上面参数中传入了uid和gid, 接着进入到了Process.start方法,源码如下:
frameworks/base/services/core/java/com/android/os/Process.java
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);
}
我们看到调用到了zygoteProcess.start方法,zygoteProcess是和zygote进程保持通信状态的,进入内部查看方法:
frameworks/base/services/core/java/com/android/os/ZygoteProcess.java
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方法:
frameworks/base/services/core/java/com/android/os/ZygoteProcess.java
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);
...
argsForZygote.add(processClass);
if (extraArgs != null) {
for (String arg : extraArgs) {
argsForZygote.add(arg);
}
}
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
可以看到前面大部分工作实在封装参数到argsForZygote,最后用于调用到zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
。其中第一个参数是一个方法,返回ZygoteState,第二个就是封装的参数argsForZygote,用于zygote进程接受请求后创建进程使用。
我们先看openZygoteSocketIfNeeded,返回一个ZygoteState, 源码如下:
frameworks/base/services/core/java/com/android/os/ZygoteProcess.java
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
/**1 与zygote进程建立连接*/
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}
/**2 连接zygote主模式返回的ZygoteState是否与应用程序进程所需要的ABI匹配,匹配就return返回*/
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
/**3 如果主模式不匹配的话,尝试连接第二种辅助模式*/
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
}
/**4 如果辅助模式匹配的话就return返回*/
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
/**5 如果都不匹配的话就抛出异常*/
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
我们在Zygote进程启动篇中分析过了在ZygoteInit的main函数中通过registerZygoteSocket注册了一个名字为zygote的socket, 这里就是尝试与zygote进程的socket通信,返回一个ZygoteState,如果最后都不匹配的话就抛出异常。
返回的ZygoteState作为参数被zygoteSendArgsAndGetResult调用,源码如下:
frameworks/base/services/core/java/com/android/os/ZygoteProcess.java
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
// 1
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
// 2
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);
}
}
从上面注释1处和注释2处我们看到,此方法的主要目的就是将请求的参数args写入到ZygoteState中,ZygoteState是ZygoteProcess的静态内部类,用于表示与Zygote进程通信的状态,到此第一部分AMS发送请求分析完毕。
我们首先回顾下Zygote进程如何处理AMS发送的请求的,不熟悉的小伙伴可以点击Zygote进程启动过程解析查看,它是通过runSelectLoop不停的循环来接受AMS发送的请求,ZygoteInit 9.0的源码和7.0的源码大同小异,我们看main方法:
frameworks/base/core/java/com/android/internal/os/ZygoteInit
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
...
Runnable caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
接着进入到了runSelectLoop,源码如下:
frameworks/base/core/java/com/android/internal/os/ZygoteServer
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;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
ZygoteConnection connection = peers.get(i);
// 2
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
return command;
} else {
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
}
}
}
}
}
在注释1处i==0说明zygote进程和system_server进程的AMS建立了连接, 通过acceptCommandPeer返回ZygoteConnection,然后将相关对象分别添加到peers和fds中。注释2处i>0说明ActivityManagerService向Zygote进程发送了一个创建应用进程的请求,然后调用ZygoteConnection的processOneCommand函数来创建一个新的应用程序进程, 进入查看源码:
frameworks/base/core/java/com/android/internal/os/ZygoteConnection
Runnable processOneCommand(ZygoteServer zygoteServer) {
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);
...
// 1
String args[] args = readArgumentList();
// 2
parsedArgs = new Arguments(args);
// 3
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
// 4
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
}
}
注释1处读取应用程序启动参数。注释2处将参数封装到Arguments对象中。注释3处开始通过Zygote.forkAndSpecialize创建应用程序进程,参数来自于注释2处,通过fork zygote进程创建应用程序进程,返回了一个pid的值,如果pid=0的话,说明是代码运行在子进程中,我们进入注释4处的handleChildProc查看:
frameworks/base/core/java/com/android/internal/os/ZygoteConnection
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
}
进入到ZygoteInit类的zygoteInit方法,源码如下:
frameworks/base/core/java/com/android/internal/os/ZygoteInit
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();
// 1
ZygoteInit.nativeZygoteInit();
// 2
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
在注释1启动Binder线程池,注释2处调用RuntimeInit.applicationInit方法:
frameworks/base/core/java/com/android/internal/os/RuntimeInit
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
final Arguments args = new Arguments(argv);
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
findStaticMain方法源码如下:
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
}
Method m;
try {
m = cl.getMethod("main", new Class[] {
String[].class });
} catch (NoSuchMethodException ex) {
}
return new MethodAndArgsCaller(m, argv);
}
findStaticMain中的className是ActivityThread,通过反射将m封装到MethodAndArgsCaller这个Runnable中,这个Runnable最终返回到了ZygoteInit的main方法中, 如下:
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
...
Runnable caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
// 1
caller.run();
}
上面注释1处调用了run方法,也就是调用了ActivityThread的main方法,那么我们的应用程序进程就创建完成,并且运行了ActivityThread。到此应用程序进程启动源码分析结束。