1.概述
要想启动一个应用程序,首先要保证这个应用程序所对应的应用程序进程已经被启动。ActivityManagerService在启动应用程序时会检查这个应用需要的应用程序进程是否存在,不存在就会请求Zygote进程将需要的应用程序进程启动。Zygote的Java框架层中,会创建一个Server端的Socket,这个Socket用来等待ActivityManagerService来请求Zygote来创建新的应用程序进程。我们知道Zygote进程通过fock自身创建新的应用程序进程,这样应用程序程序进程就会获得Zygote进程在启动时创建的虚拟机实例,还可以获得Binder线程池和消息循环,这样应用程序就可以方便的使用Binder,进行进程间通信以及消息处理机制了。
2.启动过程
1.AMS 发送创建应用程序进程请求
ActivityManagerService会通过调用startProcessLocked函数来向Zygote进程发送请求
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, boolean isTop, 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) { // If the process is known as top app, set a hint so when the process is // started, the top priority can be applied immediately to avoid cpu being // preempted by other processes before attaching the process of top app. startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */, new HostingRecord(hostingType, hostingName, isTop), ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */, false /* isolated */); } } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } }
@GuardedBy("this") final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated) { return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */, null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, null /* crashHandler */); }
进入ProcessList的startProcessLocked方法
frameworks\base\services\core\java\com\android\server\am\ProcessList.java
/** * @return {@code true} if process start is successful, false otherwise. */ @GuardedBy("mService") boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks, String abiOverride) { int uid = app.uid;//创建应用程序进程的用户ID 对gids进行创建和赋值 int[] gids = null; gids = computeGidsForProcess(mountExternal, uid, permGids, externalStorageAccess); // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. 如果entryPoint 为null则赋值为”android.app.ActivityThread” final String entryPoint = "android.app.ActivityThread"; return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime); }
@GuardedBy("mService") boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, String invokeWith, long startTime) { app.setPendingStart(true); app.setRemoved(false); synchronized (mProcLock) { app.setKilledByAm(false); app.setKilled(false); } if (app.getStartSeq() != 0) { Slog.wtf(TAG, "startProcessLocked processName:" + app.processName + " with non-zero startSeq:" + app.getStartSeq()); } if (app.getPid() != 0) { Slog.wtf(TAG, "startProcessLocked processName:" + app.processName + " with non-zero pid:" + app.getPid()); } app.setDisabledCompatChanges(null); if (mPlatformCompat != null) { app.setDisabledCompatChanges(mPlatformCompat.getDisabledChanges(app.info)); } final long startSeq = ++mProcStartSeqCounter; app.setStartSeq(startSeq); app.setStartParams(uid, hostingRecord, seInfo, startTime); app.setUsingWrapper(invokeWith != null || Zygote.getWrapProperty(app.processName) != null); mPendingStarts.put(startSeq, app); if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES, "Posting procStart msg for " + app.toShortString()); mService.mProcStartHandler.post(() -> handleProcessStart( app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal, requiredAbi, instructionSet, invokeWith, startSeq)); return true; } else { try { 启动app final Process.ProcessStartResult startResult = startProcess(hostingRecord, entryPoint, app, uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime); handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, startSeq, false); } catch (RuntimeException e) { Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e); app.setPendingStart(false); mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, false, true, false, false, app.userId, "start failure"); } return app.getPid() > 0; } }
startProcess方法
final Process.ProcessStartResult startResult; boolean regularZygote = false; if (hostingRecord.usesWebviewZygote()) { startResult = startWebView(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, app.info.packageName, app.getDisabledCompatChanges(), new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); } else if (hostingRecord.usesAppZygote()) { final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); // We can't isolate app data and storage data as parent zygote already did that. startResult = appZygote.getProcess().start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, app.info.packageName, /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap, false, false, new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); } else { 启动普通app regularZygote = true; startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags, isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs, new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); }
frameworks\base\core\java\android\os\Process.java
执行Process的start方法,调用ZYGOTE_PROCESS的start方法
/** * State associated with the zygote process. * @hide */ 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, int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, @Nullable Map<String, Pair<String, Long>> whitelistedDataInfoMap, boolean bindMountAppsData, boolean bindMountAppStorageDirs, @Nullable String[] zygoteArgs) { return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges, pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData, bindMountAppStorageDirs, zygoteArgs); }
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, int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, @Nullable Map<String, Pair<String, Long>> allowlistedDataInfoList, boolean bindMountAppsData, boolean bindMountAppStorageDirs, @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, zygotePolicyFlags, isTopApp, disabledCompatChanges, pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData, bindMountAppStorageDirs, 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(@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, int zygotePolicyFlags, boolean isTopApp, @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, @Nullable Map<String, Pair<String, Long>> allowlistedDataInfoList, boolean bindMountAppsData, boolean bindMountAppStorageDirs, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { ArrayList<String> argsForZygote = new ArrayList<>(); // --runtime-args, --setuid=, --setgid=, // and --setgroups= must go first 创建了字符串列表argsForZygote ,并将启动应用进程的启动参数保存在argsForZygote中 argsForZygote.add("--runtime-args"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); argsForZygote.add("--runtime-flags=" + runtimeFlags); synchronized(mLock) { // The USAP pool can not be used if the application will not use the systems graphics // driver. If that driver is requested use the Zygote application start path. return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), zygotePolicyFlags, argsForZygote); } }
@GuardedBy("mLock") private Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args) throws ZygoteStartFailedEx { // Throw early if any of the arguments are malformed. This means we can // avoid writing a partial response to the zygote. for (String arg : args) { // Making two indexOf calls here is faster than running a manually fused loop due // to the fact that indexOf is an optimized intrinsic. 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"); } } /* * See com.android.internal.os.ZygoteArguments.parseArgs() * 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. */ String msgStr = args.size() + "\n" + String.join("\n", args) + "\n"; if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) { try { return attemptUsapSendArgsAndGetResult(zygoteState, msgStr); } catch (IOException ex) { // If there was an IOException using the USAP pool we will log the error and // attempt to start the process through the Zygote. Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - " + ex.getMessage()); } } return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); }
调用 attemptZygoteSendArgsAndGetResult 方法
函数主要做的就是将传入的应用进程的启动参数argsForZygote写入到ZygoteState中,而ZygoteState是由openZygoteSocketIfNeeded函数返回的
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult( ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx { try { final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter; 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); } }
@GuardedBy("mLock") private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { try { attemptConnectionToPrimaryZygote(); 连接Zygote的Socket if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } if (mZygoteSecondarySocketAddress != null) { // The primary zygote didn't match. Try the secondary. attemptConnectionToSecondaryZygote(); if (secondaryZygoteState.matches(abi)) { return secondaryZygoteState; } } } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to zygote", ioe); } throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi); }
如果连接name为“zygote”的Socket返回的primaryZygoteState与当前的abi不匹配,则会连接name为“zygote_secondary”的Socket。这两个Socket区别就是:name为”zygote”的Socket是运行在64位Zygote进程中的,而name为“zygote_secondary”的Socket则运行在32位Zygote进程中。既然应用程序进程是通过Zygote进程fock产生的,当要连接Zygote中的Socket时,也需要保证位数的一致。
@GuardedBy("mLock") private void attemptConnectionToPrimaryZygote() throws IOException { if (primaryZygoteState == null || primaryZygoteState.isClosed()) { primaryZygoteState = ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress); maybeSetApiDenylistExemptions(primaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState); } }
@GuardedBy("mLock") private void attemptConnectionToSecondaryZygote() throws IOException { if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { secondaryZygoteState = ZygoteState.connect(mZygoteSecondarySocketAddress, mUsapPoolSecondarySocketAddress); maybeSetApiDenylistExemptions(secondaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState); } }
Zygote接收请求并创建应用程序进程
Socket进行连接成功并匹配abi后会返回ZygoteState类型对象,我们在分析zygoteSendArgsAndGetResult函数中讲过,会将应用进程的启动参数argsForZygote写入到ZygoteState中,这样Zygote进程就会收到一个创建新的应用程序进程的请求,我们回到ZygoteInit的main函数,
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
@UnsupportedAppUsage public static void main(String[] argv) { //注册Zygote用的Socket FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED, BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START, startTime); //预加载类和资源 preload(bootTimingsTraceLog); //启动SystemServer进程 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // The select loop returns early in the child process after a fork and // loops forever in the zygote. 等待客户端调用 caller = zygoteServer.runSelectLoop(abiList); 关闭socket finally { if (zygoteServer != null) { zygoteServer.closeServerSocket(); } } }
进入ZygoteServer的runSelectLoop
frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
Runnable runSelectLoop(String abiList) { 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); boolean multipleForksOK = !isUsapPoolEnabled() && ZygoteHooks.isIndefiniteThreadSuspensionSafe(); final Runnable command = connection.processCommand(this, multipleForksOK); // TODO (chriswailes): Is this extra check necessary? if (mIsForkChild) { // We're in the child. We should always have a command to run at // this stage if processCommand hasn't called "exec". if (command == null) { throw new IllegalStateException("command == null"); } return command; } else { // We're in the server - we should never have any commands to run. if (command != null) { throw new IllegalStateException("command != null"); } // We don't know whether the remote side of the socket was closed or // not until we attempt to read from it from processCommand. This // shows up as a regular POLLIN event in our regular processing // loop. if (connection.isClosedByPeer()) { connection.closeSocket(); peers.remove(pollIndex); socketFDs.remove(pollIndex); } } } catch (Exception e) { if (!mIsForkChild) { // We're in the server so any exception here is one that has taken // place pre-fork while processing commands or reading / writing // from the control socket. Make a loud noise about any such // exceptions so that we know exactly what failed and why. Slog.e(TAG, "Exception executing zygote command: ", e); // Make sure the socket is closed so that the other end knows // immediately that something has gone wrong and doesn't time out // waiting for a response. ZygoteConnection conn = peers.remove(pollIndex); conn.closeSocket(); socketFDs.remove(pollIndex); } else { // We're in the child so any exception caught here has happened post // fork and before we execute ActivityThread.main (or any other // main() method). Log the details of the exception and bring down // the process. Log.e(TAG, "Caught post-fork exception in child process.", e); throw e; } } finally { // Reset the child flag, in the event that the child process is a child- // zygote. The flag will not be consulted this loop pass after the // Runnable is returned. mIsForkChild = false; } } else { // Either the USAP pool event FD or a USAP reporting pipe. // If this is the event FD the payload will be the number of USAPs removed. // If this is a reporting pipe FD the payload will be the PID of the USAP // that was just specialized. The `continue` statements below ensure that // the messagePayload will always be valid if we complete the try block // without an exception. long messagePayload; try { byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length); if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(buffer)); messagePayload = inputStream.readLong(); } else { Log.e(TAG, "Incomplete read from USAP management FD of size " + readBytes); continue; } } catch (Exception ex) { if (pollIndex == usapPoolEventFDIndex) { Log.e(TAG, "Failed to read from USAP pool event FD: " + ex.getMessage()); } else { Log.e(TAG, "Failed to read from USAP reporting pipe: " + ex.getMessage()); } continue; } if (pollIndex > usapPoolEventFDIndex) { Zygote.removeUsapTableEntry((int) messagePayload); } usapPoolFDRead = true; } } }
进入 frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java的processCommand方法
Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) { if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote || !multipleOK || peer.getUid() != Process.SYSTEM_UID) { // Continue using old code for now. TODO: Handle these cases in the other path. 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.mIsTopApp, parsedArgs.mPkgDataInfoList, parsedArgs.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs); try { if (pid == 0) { // in child zygoteServer.setForkChild(); zygoteServer.closeServerSocket(); IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; return handleChildProc(parsedArgs, 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, serverPipeFd); return null; } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } } }
forkAndSpecialize函数来创建应用程序进程,参数为parsedArgs中存储的应用进程启动参数,返回值为pid。forkAndSpecialize函数主要是通过fork当前进程来创建一个子进程的,如果pid等于0,则说明是在新创建的子进程中执行的,就会调用handleChildProc函数来启动这个子进程,也就是应用程序进程
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor pipeFd, boolean isZygote) { /* * By the time we get here, the native code has closed the two actual Zygote * socket connections, and substituted /dev/null in their place. The LocalSocket * objects still need to be closed properly. */ closeSocket(); Zygote.setAppProcessName(parsedArgs, TAG); // 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) { return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mDisabledCompatChanges, parsedArgs.mRemainingArgs, null /* classLoader */); } else { return ZygoteInit.childZygoteInit( parsedArgs.mRemainingArgs /* classLoader */); } } }
调用 ZygoteInit.zygoteInit
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges, 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();在新创建的应用程序进程中创建Binder线程池 return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, classLoader); }
/** * The main function called when starting a child zygote process. This is used as an alternative * to zygoteInit(), which skips calling into initialization routines that start the Binder * threadpool. */ static Runnable childZygoteInit(String[] argv) { RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv); return RuntimeInit.findStaticMain(args.startClass, args.startArgs, /* classLoader= */null); }
调用RuntimeInit的 applicationInit方法
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges, String[] argv, ClassLoader classLoader) { // If the application calls System.exit(), terminate the process // immediately without running any shutdown hooks. It is not possible to // shutdown an Android application gracefully. Among other things, the // Android runtime shutdown hooks close the Binder driver, which can cause // leftover running threads to crash before the process actually exits. nativeSetExitWithoutCleanup(true); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges); 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); }
findStaticMain方法
protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; try { 通过反射来获得android.app.ActivityThread类 cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { 获得ActivityThread的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); } /* * 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. */ 调用MethodAndArgsCaller return new MethodAndArgsCaller(m, argv); }
MethodAndArgsCaller类内部会通过反射调用ActivityThread的main函数,讲到这里,应用程序进程就创建完成了并且运行了代表主线程的实例ActivityThread。
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 }); } 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); } } }