目录
前言
今天简单的记录一下App进程的启动过程。
继之前startActivity的分析(《》和《》)中的进程启动是一带而过的,聪明的你会发现,进程启动的大部分跟《》重合了。
正文
回到《》文章末尾的startProcessLocked()。
ActivityManagerService.java
PS: 大部分内容都略了
startProcessLocked()
@GuardedBy("this") 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) { //略 final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride); //略 }
startProcessLocked()
@GuardedBy("this") private final boolean startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride) { return startProcessLocked(app, hostingType, hostingNameStr, false /* disableHiddenApiChecks */, abiOverride); }
startProcessLocked()
@GuardedBy("this") private final boolean startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) { //日志显示,前面几个startProcessLocked()会被调用2次 //第一次app.pendingStart=false;第二次app.pendingStart=true; //因此第二次直接返回 if (app.pendingStart) { return true; } //略 try { try { final int userId = UserHandle.getUserId(app.uid); //PackageManagerService.java中检测 //(1)判断是否存在(2)判断是否安装等,如果有问题就抛出异常 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } //略 //false if (!app.isolated) { } //略 //注意,这里传入了android.app.ActivityThread final String entryPoint = "android.app.ActivityThread"; //进入下一个startProcessLocked() return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime); } catch (RuntimeException e) { forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, false, true, false, false, UserHandle.getUserId(app.userId), "start failure"); return false; } }
这里有个重点,参数中传入了entryPoint,而entryPoint是
final String entryPoint = "android.app.ActivityThread";
fork出子进程后会启动android.app.ActivityThread
startProcessLocked()
@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) { //略 //异步启动 true if (mConstants.FLAG_PROCESS_START_ASYNC) { //使用Handler的post,也就是异步执行。 //会先返回return mProcStartHandler.post(() -> { try { synchronized (ActivityManagerService.this) { final String reason = isProcStartValidLocked(app, startSeq); //reason为null if (reason != null) { app.pendingStart = false; return; } app.usingWrapper = invokeWith != null || SystemProperties.get("wrap." + app.processName) != null; mPendingStarts.put(startSeq, app); } //启动进程startProcess,关键点 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); } } catch (RuntimeException e) { synchronized (ActivityManagerService.this) { mPendingStarts.remove(startSeq); app.pendingStart = false; forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, false, true, false, false, UserHandle.getUserId(app.userId), "start failure"); } } }); return true; } else { try { final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app, uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime); handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, startSeq, false); } catch (RuntimeException e) { app.pendingStart = false; forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, false, true, false, false, UserHandle.getUserId(app.userId), "start failure"); } return app.pid > 0; } }
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); //hostingType这里是启动activity, 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 { //走这里,进入了Process 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); } }
Process.java
start()
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.java
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) { 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>(); //argsForZygote保存相关信息,进程uid,gid等等 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); 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()); } //niceName是应用包名 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); } //invokeWith为null if (invokeWith != null) { argsForZygote.add("--invoke-with"); argsForZygote.add(invokeWith); } //startChildZygote = false if (startChildZygote) { argsForZygote.add("--start-child-zygote"); } argsForZygote.add(processClass); if (extraArgs != null) { for (String arg : extraArgs) { argsForZygote.add(arg); } } synchronized(mLock) { //abi是平台架构类型,比如arm64-v8a,x86等,我这里是arm64-v8a //[重]openZygoteSocketIfNeeded() //[重]zygoteSendArgsAndGetResult()进程跟Zygote数据传输和读取返回结果 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } }
openZygoteSocketIfNeeded()
@GuardedBy("mLock") private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held"); //primaryZygoteState不为null if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { //看过Zygote启动的知道,Zygote存在主辅模式 //比如我设备是以Zygote64位主(secondary),Zygote32位辅(secondary)模式 //连接socket,这个是Zygote中创建的, primaryZygoteState = ZygoteState.connect(mSocket); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } maybeSetApiBlacklistExemptions(primaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState); } //具体使用哪种模式,跟abi有关 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); }
回归一下之前介绍的,不同设备使用的配置不一样。
下面是几个zygote相关的rc文件。
init.zygote32.rc
Zygote 进程对应的执行程序是 app_process,也就是纯32位模式。
init.zygote32_64.rc
启动两个 Zygote 进程(zygote 和 zygote_secondary),对应的执行程序分别是 app_process32(主模式)和app_process64。
init.zygote64.rc
Zygote 进程对应的执行程序是app_process64,也就是纯64位模式
init.zygote64_32.rc
启动两个 Zygote 进程(zygote 和 zygote_secondary),对应的执行程序分别是 app_process64(主模式)和app_process32。
会根据primaryZygoteState和secondaryZygoteState的初始化,进程判断,如果都不满足(启动失败了或重启中),就抛出异常!
理论上,至少有一个满足条件。
因此,经过上面执行,已建成跟Zygote进行通信了,并返回ZygoteState。
zygoteSendArgsAndGetResult()
@GuardedBy("mLock") private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx { try { //略 //ZygoteState就是上面openZygoteSocketIfNeeded()获取的 //获取writer和inputStream final BufferedWriter writer = zygoteState.writer; final DataInputStream inputStream = zygoteState.inputStream; //写启动上面组合的启动参数信息 //此时就进入ZygoteServer.java中runSelectLoop()的死循环中啦 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(); //创建ProcessStartResult对象 Process.ProcessStartResult result = new Process.ProcessStartResult(); //等待,zygote启动进程结构 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); } }
上面就是通过socket进程传输启动应用的新,因此,进入了ZygoteServer.java中runSelectLoop()中。
对于Zygote的socket的那块,推荐可以看参考文,之前我有跟过。
ZygoteServer.java
通过socket发送消息,runSelectLoop()会一直不断的循环并进行处理。
runSelectLoop()
Runnable runSelectLoop(String abiList) { //这部分第一次进入才执行,后面的进入了死循环了。 //死循环 while (true) { //略 for (int i = pollFds.length - 1; i >= 0; --i) { //采用I/O多路复用机制,当客户端发出连接请求或者数据处理请求时,则执行continue if ((pollFds[i].revents & POLLIN) == 0) { continue; } if (i == 0) { //有socket客户端连接上 ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { try { //客户端发送了请求,获取connection ZygoteConnection connection = peers.get(i); //[重]处理发送来的消息,其实这里就处理fork出子进程 //切记,返回的是Runnable,这里进入 final Runnable command = connection.processOneCommand(this); //这里要对fork有一定了解,创建子进程就是Zygote的分裂 //下面的if语句都会执行 //一个是走父进程流程关闭socket;一个是子进程流程,启动进程ActivityThread if (mIsForkChild) { //如果在子进程,command不为null if (command == null) { throw new IllegalStateException("command == null"); } return command; } else { //父进程,command为null if (command != null) { throw new IllegalStateException("command != null"); } //关闭socket等 if (connection.isClosedByPeer()) { connection.closeSocket(); peers.remove(i); fds.remove(i); } } } catch (Exception e) { //略 } finally { mIsForkChild = false; } } } } }
从socket中接收消息,然后进程fork出子进程(也就是从zygote中分裂而来)。
然后主进程流程关闭socket,子进程流程启动ActivityThread。
我们先挂住processOneCommand()这块。
ZygoteConnection.java
processOneCommand()
Runnable processOneCommand(ZygoteServer zygoteServer) { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; try { //从socket读取命令 args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { throw new IllegalStateException("IOException on command socket", ex); } //如果没有参数,直接结束 if (args == null) { isEof = true; return null; } int pid = -1; FileDescriptor childPipeFd = null; FileDescriptor serverPipeFd = null; //创建Arguments对象,这里会解析args中的命令 parsedArgs = new Arguments(args); //根据参数值进行处理 if (parsedArgs.abiListQuery) { handleAbiListQuery(); return null; } //略 //fork出子进程 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) { //子进程流程 zygoteServer.setForkChild(); zygoteServer.closeServerSocket(); IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; //[重]返回Runnable return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.startChildZygote); } else { IoUtils.closeQuietly(childPipeFd); childPipeFd = null; //如果是父进程流程 handleParentProc(pid, descriptors, serverPipeFd); return null; } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } }
handleChildProc()
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) { //关闭socket closeSocket(); //根据之前传入参数,invokeWith=null if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), pipeFd, parsedArgs.remainingArgs); throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); } else { //走这里 //isZygote为false,是依赖parsedArgs.startChildZygote if (!isZygote) { return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } else { return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } } }
ZygoteInit.java
zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { //这参数是ActivityManagerService.java中startProcessLocked()中[上面倒数第二个]传入的 //argv中带有android.app.ActivityThread参数。 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit"); RuntimeInit.redirectLogStreams(); RuntimeInit.commonInit(); ZygoteInit.nativeZygoteInit(); return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); }
RuntimeInit.java
applicationInit()
protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { nativeSetExitWithoutCleanup(true); VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args = new Arguments(argv); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); //[重]看方法名就知道,找到main方法入口 //args.startClass = android.app.ActivityThread 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) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { //查找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); } //创建MethodAndArgsCaller,MethodAndArgsCaller实现于Runnable return new MethodAndArgsCaller(m, argv); }
MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable { private final Method mMethod; private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { //Method = com.android.server.SystemServer的main函数 //这里会启动ActivityThread并执行main()方法 mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { //略 } } }
到这里,Runnable已经创建了,但之前仅仅是创建了Runnable,但没有执行run(),因此我们要回到runSelectLoop()中。
ZygoteServer.java
再次回答runSelectLoop()中,里面有这段代码[只是部分]
try { //客户端发送了请求,获取connection ZygoteConnection connection = peers.get(i); //[重]处理发送来的消息,其实这里就处理fork出子进程 //切记,返回的是Runnable,这里进入 final Runnable command = connection.processOneCommand(this); //这里要对fork有一定了解,创建子进程就是Zygote的分裂 //下面的if语句都会执行 //一个是走父进程流程关闭socket;一个是子进程流程,启动进程ActivityThread if (mIsForkChild) { //如果在子进程,command不为null if (command == null) { throw new IllegalStateException("command == null"); } return command; } else { //父进程,command为null if (command != null) { throw new IllegalStateException("command != null"); } //关闭socket等 if (connection.isClosedByPeer()) { connection.closeSocket(); peers.remove(i); fds.remove(i); } } } catch (Exception e) { //略 } finally { mIsForkChild = false; }
上面也说了fork后,会有两个执行流程,一个是父进程流程,一个是子进程流程。我们关注子进程流程。
也就是mIsForkChild为true时,此时command不为null,而是
command = new MethodAndArgsCaller(m, argv);
也就是runSelectLoop()执行结束,并返回Runnable。
fork是把父类所有的资源都拷贝一份给子进程,因此,上面退出的runSelectLoop()循环是子类的。
子类用户父类Zygote一样的代码流程。ZygoteInit.java是进入Java世界的第一扇大门!
runSelectLoop()也是在ZygoteInit.java中main()方法中的。
ZygoteInit.java
public static void main(String argv[]) { //创建ZygoteServer ZygoteServer zygoteServer = new ZygoteServer(); final Runnable caller; try { //略 //[重]循环中。对于zygote不会退出,至于fork的子进程,是会退出的 caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { throw ex; } finally { //关闭socket zygoteServer.closeServerSocket(); } //子进程退出的caller不为null if (caller != null) { caller.run(); } }
fork出的子进程才会退出runSelectLoop()循环,因此上面的call就是返回的Runnable对象,也就是这里main()方法结束后执行了
MethodAndArgsCaller.run();
然后进入了ActivityThread.java的main(),至于后面的,可以看《
参考文章
-
《》
-
《》
-
《》
-
《》
-