• Android S从桌面点击图标启动APP流程 (六)


    系列文章

    Android S从桌面点击图标启动APP流程 (一)
    Android S从桌面点击图标启动APP流程 (二)

    Android S从桌面点击图标启动APP流程 (三)

    Android S从桌面点击图标启动APP流程 (四)

    Android S从桌面点击图标启动APP流程 (五)

    Android 12的源码链接:

    android 12 aosphttp://aospxref.com/android-12.0.0_r3/上文讲到了 Process.start, 这里接着往下讲解

    ZygoteProcess#start

    frameworks/base/core/java/android/os/ZygoteProcess.java

    1. public final Process.ProcessStartResult start(@NonNull final String processClass,
    2. final String niceName,
    3. int uid, int gid, @Nullable int[] gids,
    4. int runtimeFlags, int mountExternal,
    5. int targetSdkVersion,
    6. @Nullable String seInfo,
    7. @NonNull String abi,
    8. @Nullable String instructionSet,
    9. @Nullable String appDataDir,
    10. @Nullable String invokeWith,
    11. @Nullable String packageName,
    12. int zygotePolicyFlags,
    13. boolean isTopApp,
    14. @Nullable long[] disabledCompatChanges,
    15. @Nullable Map>
    16. pkgDataInfoMap,
    17. @Nullable Map>
    18. allowlistedDataInfoList,
    19. boolean bindMountAppsData,
    20. boolean bindMountAppStorageDirs,
    21. @Nullable String[] zygoteArgs) {
    22. // TODO (chriswailes): Is there a better place to check this value?
    23. if (fetchUsapPoolEnabledPropWithMinInterval()) {
    24. informZygotesOfUsapPoolStatus();
    25. }
    26. try {
    27. return startViaZygote(processClass, niceName, uid, gid, gids,
    28. runtimeFlags, mountExternal, targetSdkVersion, seInfo,
    29. abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
    30. packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
    31. pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
    32. bindMountAppStorageDirs, zygoteArgs);
    33. } catch (ZygoteStartFailedEx ex) {
    34. Log.e(LOG_TAG,
    35. "Starting VM process through Zygote failed");
    36. throw new RuntimeException(
    37. "Starting VM process through Zygote failed", ex);
    38. }
    39. }

    ZygoteProcess#startViaZygote

    该过程主要工作是生成argsForZygote数组

    frameworks/base/core/java/android/os/ZygoteProcess.java

    1. private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
    2. @Nullable final String niceName,
    3. final int uid, final int gid,
    4. @Nullable final int[] gids,
    5. int runtimeFlags, int mountExternal,
    6. int targetSdkVersion,
    7. @Nullable String seInfo,
    8. @NonNull String abi,
    9. @Nullable String instructionSet,
    10. @Nullable String appDataDir,
    11. @Nullable String invokeWith,
    12. boolean startChildZygote,
    13. @Nullable String packageName,
    14. int zygotePolicyFlags,
    15. boolean isTopApp,
    16. @Nullable long[] disabledCompatChanges,
    17. @Nullable Map>
    18. pkgDataInfoMap,
    19. @Nullable Map>
    20. allowlistedDataInfoList,
    21. boolean bindMountAppsData,
    22. boolean bindMountAppStorageDirs,
    23. @Nullable String[] extraArgs)
    24. throws ZygoteStartFailedEx {
    25. ArrayList argsForZygote = new ArrayList<>();
    26. // --runtime-args, --setuid=, --setgid=,
    27. // and --setgroups= must go first
    28. argsForZygote.add("--runtime-args");
    29. argsForZygote.add("--setuid=" + uid);
    30. argsForZygote.add("--setgid=" + gid);
    31. argsForZygote.add("--runtime-flags=" + runtimeFlags);
    32. if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
    33. argsForZygote.add("--mount-external-default");
    34. } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
    35. argsForZygote.add("--mount-external-installer");
    36. } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
    37. argsForZygote.add("--mount-external-pass-through");
    38. } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
    39. argsForZygote.add("--mount-external-android-writable");
    40. }
    41. argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
    42. // --setgroups is a comma-separated list
    43. if (gids != null && gids.length > 0) {
    44. final StringBuilder sb = new StringBuilder();
    45. sb.append("--setgroups=");
    46. final int sz = gids.length;
    47. for (int i = 0; i < sz; i++) {
    48. if (i != 0) {
    49. sb.append(',');
    50. }
    51. sb.append(gids[i]);
    52. }
    53. argsForZygote.add(sb.toString());
    54. }
    55. if (niceName != null) {
    56. argsForZygote.add("--nice-name=" + niceName);
    57. }
    58. if (seInfo != null) {
    59. argsForZygote.add("--seinfo=" + seInfo);
    60. }
    61. if (instructionSet != null) {
    62. argsForZygote.add("--instruction-set=" + instructionSet);
    63. }
    64. if (appDataDir != null) {
    65. argsForZygote.add("--app-data-dir=" + appDataDir);
    66. }
    67. if (invokeWith != null) {
    68. argsForZygote.add("--invoke-with");
    69. argsForZygote.add(invokeWith);
    70. }
    71. if (startChildZygote) {
    72. argsForZygote.add("--start-child-zygote");
    73. }
    74. if (packageName != null) {
    75. argsForZygote.add("--package-name=" + packageName);
    76. }
    77. if (isTopApp) {
    78. argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);
    79. }
    80. ......
    81. argsForZygote.add(processClass);
    82. if (extraArgs != null) {
    83. Collections.addAll(argsForZygote, extraArgs);
    84. }
    85. synchronized(mLock) {
    86. // The USAP pool can not be used if the application will not use the systems graphics
    87. // driver. If that driver is requested use the Zygote application start path.
    88. 根据当前的abi来选择与zygote还是zygote64来进行通信。
    89. return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
    90. zygotePolicyFlags,
    91. argsForZygote);
    92. }
    93. }

    ZygoteProcess#zygoteSendArgsAndGetResult

    这个方法的主要功能是通过socket通道向Zygote进程发送一个参数列表,然后进入阻塞等待状态,直到远端的socket服务端发送回来新创建的进程pid才返回。

    frameworks/base/core/java/android/os/ZygoteProcess.java

    1. private Process.ProcessStartResult zygoteSendArgsAndGetResult(
    2. ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList args)
    3. throws ZygoteStartFailedEx {
    4. // Throw early if any of the arguments are malformed. This means we can
    5. // avoid writing a partial response to the zygote.
    6. for (String arg : args) {
    7. // Making two indexOf calls here is faster than running a manually fused loop due
    8. // to the fact that indexOf is an optimized intrinsic.
    9. if (arg.indexOf('\n') >= 0) {
    10. throw new ZygoteStartFailedEx("Embedded newlines not allowed");
    11. } else if (arg.indexOf('\r') >= 0) {
    12. throw new ZygoteStartFailedEx("Embedded carriage returns not allowed");
    13. }
    14. }
    15. /*
    16. * See com.android.internal.os.ZygoteArguments.parseArgs()
    17. * Presently the wire format to the zygote process is:
    18. * a) a count of arguments (argc, in essence)
    19. * b) a number of newline-separated argument strings equal to count
    20. *
    21. * After the zygote process reads these it will write the pid of
    22. * the child or -1 on failure, followed by boolean to
    23. * indicate whether a wrapper process was used.
    24. */
    25. String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
    26. if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
    27. try {
    28. return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
    29. } catch (IOException ex) {
    30. // If there was an IOException using the USAP pool we will log the error and
    31. // attempt to start the process through the Zygote.
    32. Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
    33. + ex.getMessage());
    34. }
    35. }
    36. return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    37. }

    ZygoteProcess#attemptZygoteSendArgsAndGetResult

    frameworks/base/core/java/android/os/ZygoteProcess.java

    1. private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
    2. ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    3. try {
    4. final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
    5. final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
    6. zygoteWriter.write(msgStr);
    7. zygoteWriter.flush();
    8. // Always read the entire result from the input stream to avoid leaving
    9. // bytes in the stream for future process starts to accidentally stumble
    10. // upon.
    11. Process.ProcessStartResult result = new Process.ProcessStartResult();
    12. 等待socket服务端-zygote返回新创建的进程pid;
    13. result.pid = zygoteInputStream.readInt();
    14. result.usingWrapper = zygoteInputStream.readBoolean();
    15. if (result.pid < 0) {
    16. throw new ZygoteStartFailedEx("fork() failed");
    17. }
    18. return result;
    19. } catch (IOException ex) {
    20. zygoteState.close();
    21. Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
    22. + ex.toString());
    23. throw new ZygoteStartFailedEx(ex);
    24. }
    25. }

    system_server进程通过调用attemptZygoteSendArgsAndGetResult()方法通过socket方式向Zygote进程发送消息,这样会唤醒Zygote进程,来响应socket客户端的请求(即system_server端),接下来的操作便是在Zygote来创建进程

    ZygoteInit#main

    然后会走进zygote进程创建进程,由于步骤太多,此处省略,直接到ActivityThread.main这里开始讲解。后文接着讲ActivityThread#main

    太多了,写不下去了,本系列暂停更新。😂

     

     

  • 相关阅读:
    智能制造工厂刀具使用RFID产线管理系统的重要性
    C 语言 二分法 查找。
    指定元素懒加载
    Linux Shell脚本自动化编程实战【1.4 shell特性 Login Nologin】
    基于python+TensorFlow+Django卷积网络算法+深度学习模型+蔬菜识别系统
    groovy在SpringBoot中的使用
    win10安装Adobe 2022全新体验安装教程 你觉得到底香不香
    拉线位移传感器要符合适应目前大方向
    福州大学 2022~2023 学年第 1 学期考试 A 卷压轴题参考答案
    钉钉自动打卡
  • 原文地址:https://blog.csdn.net/weixin_41028555/article/details/133926288