上一篇最后分析到:因为我们现在做的假设是应用的冷启动,所以系统中是还没有对应的进程的,需要通过startSpecificActivityLocked
方法来创建对应的进程。这一篇我们从这个方法开始
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // 这里再次检查应用进程是否已经启动 ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); // 如果不为空,代表Activity所在进程已经启动 if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode, mService.mProcessStats); } // 这里会真正的startActivity realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } } // 进程不存在,会调用ActivityManagerService的startProcessLocked mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); } |
上面的过程很简单,在启动Activity所在进程前会再次检查进程是否已经启动,只有确认进程没有启动的情况下才会调用ActivityManagerService的startProcessLocked方法来启动进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
// 由另一个同名重载函数调进来 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; if (!isolated) { // 这里和前一步一样,还是检查进程是否已经启动了 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); checkTime(startTime, "startProcess: after getProcessRecord"); ................................. } else { // 是isolated应用 app = null; } if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName + " app=" + app + " knownToBeDead=" + knownToBeDead + " thread=" + (app != null ? app.thread : null) + " pid=" + (app != null ? app.pid : -1)); // app不为空,而且app的pid大于零表示已经存在对应的进程了 if (app != null && app.pid > 0) { if ((!knownToBeDead && !app.killed) || app.thread == null) { // 有pid表示应用已经加载,但是需要等待线程起来 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); app.addPackage(info.packageName, info.versionCode, mProcessStats); checkTime(startTime, "startProcess: done, added package to proc"); return app; } if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app); checkTime(startTime, "startProcess: bad proc running, killing"); killProcessGroup(app.uid, app.pid); handleAppDiedLocked(app, true, true); checkTime(startTime, "startProcess: done killing old proc"); } String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null; // app为空表示进程还没有起来,这里符合我们冷启动的假设 if (app == null) { checkTime(startTime, "startProcess: creating new process record"); // 创建一个进程Record,这个方法比较简单,下面就不分析了 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); if (app == null) { Slog.w(TAG, "Failed making new process record for " + processName + "/" + info.uid + " isolated=" + isolated); return null; } app.crashHandler = crashHandler; app.isolatedEntryPoint = entryPoint; app.isolatedEntryPointArgs = entryPointArgs; checkTime(startTime, "startProcess: done creating new process record"); } else { ............................ } // 如果系统还没有准备好,需要挂起改应用的启动 if (!mProcessesReady && !isAllowedWhileBooting(info) && !allowWhileBooting) { if (!mProcessesOnHold.contains(app)) { mProcessesOnHold.add(app); } if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "System not ready, putting on hold: " + app); checkTime(startTime, "startProcess: returning with proc on hold"); return app; } checkTime(startTime, "startProcess: stepping in to startProcess"); // 调用startProcessLocked final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride); checkTime(startTime, "startProcess: done starting proc!"); return success ? app : null; } |
最后会调用到startProcessLocked,之后会调用到几个同名的startProcessLocked方法,我们只看最后一个有实质内容的startProcessLocked方法好了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
private final boolean startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) // 延迟启动 if (app.pendingStart) { return true; } long startTime = SystemClock.elapsedRealtime(); // 对应用的PID进行处理 if (app.pid > 0 && app.pid != MY_PID) { checkTime(startTime, "startProcess: removing from pids map"); synchronized (mPidsSelfLocked) { mPidsSelfLocked.remove(app.pid); mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); } checkTime(startTime, "startProcess: done removing from pids map"); app.setPid(0); } if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, "startProcessLocked removing on hold: " + app); mProcessesOnHold.remove(app); checkTime(startTime, "startProcess: starting to update cpu stats"); updateCpuStats(); checkTime(startTime, "startProcess: done updating cpu stats"); try { try { // 根据应用的uid获取当前userid 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 { // 这里通过PackageManagerService获取应用所归属的组id // Linux的组id会映射到框架层的不同权限 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(); } // 添加一些共享的权限,例如共享一些共享库和访问一下用户资源 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"); if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { ........................ } int runtimeFlags = 0; // 应用是否带有调试标志 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { ....................... } // 应用是否带有安全模式启动的标志或者系统以安全模式启动 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mSafeMode == true) { runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; } // 省略的内容都是根据app或者系统状态设置一些调试状态位 ............................. // 判断是否是特权APP,如果是特权APP需要从system分区中加载OAT文件 // 以确保应用的完整和安全 if (app.info.isPrivilegedApp() && DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) { runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; } // 对滴啊用Hidden API的处理???? if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) { app.info.maybeUpdateHiddenApiEnforcementPolicy( mHiddenApiBlacklist.getPolicyForPrePApps(), mHiddenApiBlacklist.getPolicyForPApps()); @HiddenApiEnforcementPolicy int policy = app.info.getHiddenApiEnforcementPolicy(); int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT); if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) { throw new IllegalStateException("Invalid API policy: " + policy); } runtimeFlags |= policyBits; } String invokeWith = null; // 可调试的app内部可能会包含一个wrap.sh脚本 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { if (new File(wrapperFileName).exists()) { invokeWith = "/system/bin/logwrapper " + wrapperFileName; } } finally { StrictMode.setThreadPolicy(oldPolicy); } } String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; if (requiredAbi == null) { requiredAbi = Build.SUPPORTED_ABIS[0]; } String instructionSet = null; if (app.info.primaryCpuAbi != null) { instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); } app.gids = gids; app.requiredAbi = requiredAbi; app.instructionSet = instructionSet; // the per-user SELinux context must be set if (TextUtils.isEmpty(app.info.seInfoUser)) { Slog.wtf(TAG, "SELinux tag not defined", new IllegalStateException("SELinux tag not defined for " + app.info.packageName + " (uid " + app.uid + ")")); } final String seInfo = app.info.seInfo + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); // 启动应用的入口类 final String entryPoint = "android.app.ActivityThread"; // 调用startProcessLocked启动应用,如果成功会返回启动应用的PID,否则会抛出RuntimeException return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime); } catch (RuntimeException e) { Slog.e(TAG, "Failure starting process " + app.processName, e); forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, false, true, false, false, UserHandle.getUserId(app.userId), "start failure"); return false; } } |
上面的过程比较容易理解,主要是进行一些启动前的处理,紧接着分析startProcessLocked方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
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的状态 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); // 同步创建还是异步创建 if (mConstants.FLAG_PROCESS_START_ASYNC) { if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES, "Posting procStart msg for " + app.toShortString()); mProcStartHandler.post(() -> { ........................ 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 { 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) { Slog.e(TAG, "Failure starting process " + app.processName, 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进行进程创建。下面我们简单分析一下整个的调用流程,在必要的地方我们再详细分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
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) { 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}); --------------------------------------------------------------------------------->>>>>>> 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); } ----------------------------------------------------------------------->>>>>>> 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) { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */, zygoteArgs); |
上面整个的调用过程,最后会调用到startViaZygote,我们都知道进行最后肯定是需要通过zygote通过fork进程来创建的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
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.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设置应用所属gid组,前面也介绍过 // Android上层的权限机制映射到底层是通过gid组来实现的 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); } // selinux权限设置 if (seInfo != null) { argsForZygote.add("--seinfo=" + seInfo); } if (instructionSet != null) { argsForZygote.add("--instruction-set=" + instructionSet); } // app应用的home目录 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) { // 讲构造的启动字串传送到zygote服务 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } } |
上面是对参数进行解析,然后构造出zygote服务端能够识别的方式,再将构造好的参数发送到zygote服务。最后调用openZygoteSocketIfNeeded就是为应用的abi找到合适的zygote服务,因为从Android 5.0之后,Android支持64位系统了,需要通过应用的abi寻找合适的zygote服务。下面分析openZygoteSocketIfNeeded方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held"); // 判断主zygote是否启动,主zygote在64位系统是zygote64,32位系统就只有zygote了 if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(mSocket); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } // 向zygote中设置Api黑名单 maybeSetApiBlacklistExemptions(primaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState); } if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } // 如果主zygote不匹配的话,尝试使用次zygote if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try { // 通过connect连接到zygote 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); } |
openZygoteSocketIfNeeded的内容比较简单,主要是为改应用寻找合适的zygote去执行。另外要提一下的是,上面还设置了API黑名单,目前猜测可能是有一些API已经不能被反射调用了,具体情况还需要后续做深入分析。这里我们先接着前一步进行分析,openZygoteSocketIfNeeded已经找到合适的zygote了,那么接着就是zygoteSendArgsAndGetResult调用了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx { try { // 首先分析传进来的参数,如果有恶意的参数,直接跑出异常,停止执行 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"); } } // 对参数进行解析,目前写到zygote服务的格式是: // 1. 首先讲参数的个数写到对端 // 2. 然后讲参数一行一行的写到对端,需要换行符分割每个参数 // 如果zygote读取参数并执行成功,会将新进程pid写回给请求端 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(); Process.ProcessStartResult result = new Process.ProcessStartResult(); // 读取对端返回的结果 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); } } |
这上面都只是在准备一些数据,然后传送给zygote,但是没有看到和zygote是如何连接的。其实zygote连接的过程还是在openZygoteSocketIfNeeded方法里面完成的,这里的连接过程就是一个文件socket的创建过程一样,所以这里就不细说了,有兴趣的同学可以openZygoteSocketIfNeeded方法里面primaryZygoteState = ZygoteState.connect(mSocket);
这行代码就行。
zygote处理
如果上面的内容没问题,那么现在已经连接到zygote去了。我们在分析zygote的时候有提到,zygote会在他的main方法中等待请求的到来,具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public static void main(String argv[]) { ZygoteServer zygoteServer = new ZygoteServer(); // 创建zygote ZygoteHooks.startZygoteNoThreadCreation(); ......................... // 预加载资源 if (!enableLazyPreload) { bootTimingsTraceLog.traceBegin("ZygotePreload"); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload(bootTimingsTraceLog); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); bootTimingsTraceLog.traceEnd(); // ZygotePreload } else { Zygote.resetNicePriority(); } .......................... // 启动systemServer进程 if (startSystemServer) { Runnable r = forkSystemServer(abiList, socketName, zygoteServer); // {@code r == null} in the parent (zygote) process, and {@code r != null} in the // child (system_server) process. if (r != null) { r.run(); return; } } // runSelectLoop方法就和我们这的关系比较大了。等待客户端连接 caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception", ex); throw ex; } finally { zygoteServer.closeServerSocket(); } } |
所以zygote的具体处理的事情都是在runSelectLoop里面完成。我们下面来看看,一些不相干代码就省略了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Runnable runSelectLoop(String abiList) { ......................... // 一个死循环处理 while (true) { // 通过pull方式处理连接 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 (i == 0) { ...................... } else { try { // 获取客户端发送过来的事件 ZygoteConnection connection = peers.get(i); // 处理事件 final Runnable command = connection.processOneCommand(this); ....................... } } |
上面可以看出,具体处理客户端请求的代码都运行在processOneCommand方法里面。我们来看看这个方法是怎么处理的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
Runnable processOneCommand(ZygoteServer zygoteServer) { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; try { // 读取参数 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对象,之后一大段代码都是在对相应的参数进行处理 parsedArgs = new Arguments(args); if (parsedArgs.abiListQuery) { handleAbiListQuery(); return null; } if (parsedArgs.preloadDefault) { handlePreload(); return null; } // 下面的代码类似上面的处理过程,略过 ................................. // 处理zygote中打开的端口,以避免传递到子进程导致内存泄露 int [] fdsToClose = { -1, -1 }; FileDescriptor fd = mSocket.getFileDescriptor(); if (fd != null) { fdsToClose[0] = fd.getInt$(); } fd = zygoteServer.getServerSocketFileDescriptor(); if (fd != null) { fdsToClose[1] = fd.getInt$(); } fd = null; // 调用forkAndSpecialize创建子进程 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 { // pid == 0 表示子进程 if (pid == 0) { zygoteServer.setForkChild(); zygoteServer.closeServerSocket(); IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; // 子进程进行具体的事务处理 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); } } |
上面的代码处理过后就非常简单了,先对参数进行处理之后就是通过forkAndSpecialize创建进程,而forkAndSpecialize最后会通过JNI调用到底层去,通过Linux的fork方法产生子进程,然后父子进程在分别完成不同的任务。forkAndSpecialize的内容比较简单,这里就不分析了,我们接着看子进程具体处理那些事务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) { // 关闭一些不使用的文件描述符和socket端口 closeSocket(); if (descriptors != null) { try { Os.dup2(descriptors[0], STDIN_FILENO); Os.dup2(descriptors[1], STDOUT_FILENO); Os.dup2(descriptors[2], STDERR_FILENO); for (FileDescriptor fd: descriptors) { IoUtils.closeQuietly(fd); } } catch (ErrnoException ex) { Log.e(TAG, "Error reopening stdio", ex); } } if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); // 理论上不会走这里,不然就跑出异常终止运行了 if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), pipeFd, parsedArgs.remainingArgs); // Should not get here. throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); } else { if (!isZygote) { // 普通的应用最后调用zygoteInit方法,下面接着分析 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } else { return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } } } 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"); // 重定位log输出,没什么好说的 RuntimeInit.redirectLogStreams(); // Android运行时初始化 RuntimeInit.commonInit(); // 这里也是通过JNI调用,看样子是做一些底层的初始化,这里也不分析 ZygoteInit.nativeZygoteInit(); // 最后通过Android运行时创建application对象,下面接着分析 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); } protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { // 如果应用调用了System.exit(),在这里需要做一些处理 nativeSetExitWithoutCleanup(true); // 设置栈和targetSDK版本 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args = new Arguments(argv); // The end of of the RuntimeInit event (see #zygoteInit). Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); // 最最最重要的还是这个方法 return findStaticMain(args.startClass, args.startArgs, classLoader); } |
上面的方法进过一连串的调用、处理后,最后会调用到findStaticMain方法,findStaticMain才是最最最关键的,因为这里是具体执行之前传经来的方法的main方法的地方。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
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); } // 调用ActivityThread的main方法并返回 return new MethodAndArgsCaller(m, argv); } |
这最后是通过反射的方法调用到android.app.ActivityThread的main方法,之后都会在android.app.ActivityThread中执行,具体内容我们下一篇再进行分析,这一篇我们就到这里了。