系列文章
Android S从桌面点击图标启动APP流程 (一)
Android S从桌面点击图标启动APP流程 (二)
Android 12的源码链接:
android 12 aosp
http://aospxref.com/android-12.0.0_r3/上文讲到了 Process.start, 这里接着往下讲解
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
> - pkgDataInfoMap,
- @Nullable Map
> - 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);
- }
- }
该过程主要工作是生成argsForZygote数组
frameworks/base/core/java/android/os/ZygoteProcess.java
- 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
> - pkgDataInfoMap,
- @Nullable Map
> - allowlistedDataInfoList,
- boolean bindMountAppsData,
- boolean bindMountAppStorageDirs,
- @Nullable String[] extraArgs)
- throws ZygoteStartFailedEx {
- ArrayList
argsForZygote = new ArrayList<>(); -
- // --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);
- if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
- argsForZygote.add("--mount-external-default");
- } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
- argsForZygote.add("--mount-external-installer");
- } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
- argsForZygote.add("--mount-external-pass-through");
- } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
- argsForZygote.add("--mount-external-android-writable");
- }
-
- argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
-
- // --setgroups is a comma-separated list
- if (gids != null && gids.length > 0) {
- final StringBuilder sb = new StringBuilder();
- sb.append("--setgroups=");
-
- final 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);
- }
-
- if (seInfo != null) {
- argsForZygote.add("--seinfo=" + seInfo);
- }
-
- if (instructionSet != null) {
- argsForZygote.add("--instruction-set=" + instructionSet);
- }
-
- 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");
- }
-
- if (packageName != null) {
- argsForZygote.add("--package-name=" + packageName);
- }
-
- if (isTopApp) {
- argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);
- }
- ......
-
- argsForZygote.add(processClass);
-
- if (extraArgs != null) {
- Collections.addAll(argsForZygote, extraArgs);
- }
-
- 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.
- 根据当前的abi来选择与zygote还是zygote64来进行通信。
- return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
- zygotePolicyFlags,
- argsForZygote);
- }
- }
这个方法的主要功能是通过socket通道向Zygote进程发送一个参数列表,然后进入阻塞等待状态,直到远端的socket服务端发送回来新创建的进程pid才返回。
frameworks/base/core/java/android/os/ZygoteProcess.java
- private Process.ProcessStartResult zygoteSendArgsAndGetResult(
- ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList
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);
- }
frameworks/base/core/java/android/os/ZygoteProcess.java
- 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();
- 等待socket服务端-zygote返回新创建的进程pid;
- 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);
- }
- }
system_server进程通过调用attemptZygoteSendArgsAndGetResult()方法通过socket方式向Zygote进程发送消息,这样会唤醒Zygote进程,来响应socket客户端的请求(即system_server端),接下来的操作便是在Zygote来创建进程
然后会走进zygote进程创建进程,由于步骤太多,此处省略,直接到ActivityThread.main这里开始讲解。后文接着讲ActivityThread#main
太多了,写不下去了,本系列暂停更新。😂