赞
踩
在前面我们从源码层面分析了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。到此应用程序进程启动源码分析结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。