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

系列文章

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

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

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

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

Android 12的源码链接:

android 12 aospicon-default.png?t=N7T8http://aospxref.com/android-12.0.0_r3/上文讲到了 Process.start, 这里接着往下讲解

ZygoteProcess#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<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);}}

ZygoteProcess#startViaZygote

该过程主要工作是生成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<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 firstargsForZygote.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 listif (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);}}

ZygoteProcess#zygoteSendArgsAndGetResult

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

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

    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);}

ZygoteProcess#attemptZygoteSendArgsAndGetResult

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来创建进程

ZygoteInit#main

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/122175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【OpenCV实现图像的算数运算,性能测试和优化,改变颜色空间】

文章目录 OpenCV功能概要图像的算数运算性能测试和优化改变颜色空间对象追踪 OpenCV功能概要 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习库&#xff0c;提供了丰富的图像处理和计算机视觉算法。它支持多种编程语言&…

Java中的volatile关键字

volatile是什么&#xff1f; "volatile"是一个关键字&#xff0c;用于修饰变量。它的作用是告诉编译器该变量可能会在意料之外的时候被修改&#xff0c;因此编译器在对该变量进行优化时需要特别小心。 具体来说&#xff0c;当一个变量被声明为"volatile"…

算法通过村第十七关-贪心|白银笔记|贪心高频问题

文章目录 前言区间问题判断区间是否重复合并区间插入区间 字符串分割加油站问题总结 前言 提示&#xff1a;如果生活把你的门关上了&#xff0c;那你就再打开&#xff0c;这就是门&#xff0c;门就是这样的。 --佚名 贪婪的思想不一定要理解的很透彻&#xff0c;但是贪婪的问题…

Cookie技术

Cookie中文名称为小型文本文件&#xff0c;指某些网站为了辨别用户身份、进行会话跟踪而储存在用户本地终端上的数据。 Cookie是由服务器端生成&#xff0c;发送给User-Agent&#xff08;—般是浏览器&#xff09;&#xff0c;浏览器会将Cookie的key/value保存到某个目录下的文…

软考系列(系统架构师)- 2013年系统架构师软考案例分析考点

试题一 软件架构&#xff08;根据描述填表、ESB 定义和功能&#xff09; 【问题1】&#xff08;10分&#xff09; 服务建模是对Ramp Coordination信息系统进行集成的首要工作&#xff0c;公司的架构师首先对Ramp Coordination信息系统进行服务建模&#xff0c;识别出系统中的两…

从Mysql架构看一条查询sql的执行过程

1. 通信协议 我们的程序或者工具要操作数据库&#xff0c;第一步要做什么事情&#xff1f; 跟数据库建立连接。 首先&#xff0c;MySQL必须要运行一个服务&#xff0c;监听默认的3306端口。在我们开发系统跟第三方对接的时候&#xff0c;必须要弄清楚的有两件事。 第一个就是通…

uniapp开发小程序 小米手机真机bottom:0无效 底部间隙 设备安全区域处理办法

uniApp自定义导航 CSS设置 bottom:0竟然无效&#xff0c;而iphone和开发模拟器没有问题 height: 150rpx;position: fixed;left: 0;right: 0;bottom: calc(var(--window-bottom,0)); 网上查了各种方法&#xff0c;包括设置bottom:-20啊以及 padding-bottom: constant(safe-are…

静电模型PIC方法的Matlab仿真设计

任务要求&#xff1a; 采用PIC模拟方法的静电模型来模拟多环形电子注在圆柱系统中的运动轨迹。模拟电子枪阴极表面发射电子注&#xff0c;电子在静态场的作用下运动直至稳定的运动过程。其中 系统长&#xff1a;0.01m 系统半径&#xff1a;0.005m 入射的每个宏电子电流&#x…

业界中说的快速原型法是什么

快速原型法是一种软件开发过程&#xff0c;其核心思想是在开发初期快速构建一个系统的原型&#xff0c;即一个工作模型&#xff0c;以便用户和开发者能够更好地理解系统的需求和功能。这种方法强调快速迭代和用户参与&#xff0c;目的是更早地发现和修正问题&#xff0c;从而提…

Ubuntu中查看电脑有多少个核——lscpu

1. 使用lscpu命令: 打开终端并输入以下命令: lscpu你会看到与CPU相关的详细信息。查找"CPU(s)"这一行来看总的核心数。另外&#xff0c;“Core(s) per socket”表示每个插槽或每个物理CPU的核数&#xff0c;“Socket(s)”表示物理CPU的数量。将这两个值相乘即得到总…

IO流框架,缓冲流

一.缓冲流有什么优点 Java中的缓冲流&#xff08;Buffered Stream&#xff09;具有以下优势&#xff1a; 提高效率&#xff1a;缓冲流通过在内存中缓存一部分数据&#xff0c;减少了直接从内存到磁盘或从磁盘到内存的频繁IO操作&#xff0c;从而提高了读写效率。缓冲区大小调整…

蓝桥杯双周赛算法心得——通关(哈希+小根堆)

大家好&#xff0c;我是晴天学长&#xff0c;这是很重要的贪心思维题&#xff0c;哈希的存法和小根堆的表示很重要。 1) .通关 2) .算法思路 通关 用hash&#xff08;int[]&#xff09;存点的子节点并按输入顺序存关卡的号码&#xff08;输入顺序就是&#xff09; 列如&#…

RabbitMQ-死信交换机和死信队列

1. 简介 1.1 DLX简介 DLX: Dead-Letter-Exchange 死信交换器&#xff0c;死信邮箱 当消息成为Dead message后&#xff0c;可以被重新发送到另一个交换机&#xff0c;这个交换机就是DLX。 如下图所示&#xff1a; 其实死信队列就是一个普通的交换机&#xff0c;有些队列的消息…

初步认识 Web Components 并实现一个按钮

目录 1.Web Components 基本概念 1.1 三个场景 1.2 是什么 2.使用 Custom Elements 实现一个按钮 2.1 概念介绍 2.1.1 Shadow DOM 2.1.2 Element.attachShadow() 2.1.3 在组件中 使用 Shadow DOM 基本步骤 2.1.4 attributeChangedCallback 2.1.5 get observedAttribu…

Spring Security漏洞防护—HttpFirewall和 HTTPS

一、HttpFirewall Spring Security有几个领域&#xff0c;你所定义的 pattern 会针对传入的请求进行测试&#xff0c;以决定应该如何处理请求。这发生在 FilterChainProxy 决定请求应该通过哪个过滤链时&#xff0c;以及 FilterSecurityInterceptor 决定哪些安全约束适用于请求…

计算机毕设 flink大数据淘宝用户行为数据实时分析与可视化

文章目录 0 前言1、环境准备1.1 flink 下载相关 jar 包1.2 生成 kafka 数据1.3 开发前的三个小 tip 2、flink-sql 客户端编写运行 sql2.1 创建 kafka 数据源表2.2 指标统计&#xff1a;每小时成交量2.2.1 创建 es 结果表&#xff0c; 存放每小时的成交量2.2.2 执行 sql &#x…

Servlet 与Spring对比!

前言&#xff1a; Spring相关的框架知识&#xff0c;算是目前公司在用的前沿知识了&#xff0c;很重要&#xff01;&#xff01; 那么以Spring为基础的框架有几个&#xff1f; 以Spring为基础的框架包括若干模块&#xff0c;其中主要的有Spring Framework、Spring Boot、Spring…

Mybatis基础

文章目录 Mybatis基础XML语言概述使用Mybatis配置Mybatis增删改查复杂查询事务操作动态 SQLifchoose、when、otherwise 缓存机制注解开发 Mybatis基础 虽然我们能够通过JDBC来连接和操作数据库&#xff0c;但是哪怕只是完成一个SQL语句的执行&#xff0c;都需要编写大量的代码…

Tensorflow2 中模型训练标签顺序和预测结果标签顺序不一致问题解决办法

本篇文章将详细介绍Tensorflow2.x中模型训练标签顺序和预测结果标签顺序不一致问题&#xff0c;这个问题如果考虑不周&#xff0c;或者标签顺序没有控制好的情况下会出现预测结果精度极其不准确的情况。 训练数据集的结构&#xff1a;数据集有超过10的类别数&#xff0c;这里包…

【Java 进阶篇】Java HTTP 请求消息详解

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于传输超文本的应用层协议&#xff0c;广泛用于构建互联网应用。在Java中&#xff0c;我们经常需要发送HTTP请求来与远程服务器进行通信。本文将详细介绍Java中HTTP请求消息的各个部分&#xff0c;包括请求行、…