安卓14中Zygote初始化流程及源码分析
文章目录
- 日志抓取
- 结合日志与源码分析
- systemServer zygote创建时序图
- 一般应用 zygote 创建时序图
- 向 zygote socket 发送数据时序图
本文首发地址 https://h89.cn/archives/298.html
最新更新地址 https://gitee.com/chenjim/chenjimblog
本文主要结合日志和代码看安卓 14 中 Zygote 启动相关流程
日志抓取
先抓一份开机日志
adb reboot && adb wait-for-device shell logcat -b all > all.log
过滤出 zygote 相关日志
cat all.log | grep -i Zygote > all.Zygote.log
以上完整日志文件 https://gitee.com/chenjim/ResData/tree/master/boot.01.log
我们看一下 日志文件 all.Zygote.log , 部分日志如下
07-01 21:43:43.516 0 0 I init : Added '/system/etc/init/hw/init.zygote64.rc' to import list
07-01 21:43:43.516 0 0 I init : Parsing file /system/etc/init/hw/init.zygote64.rc...
07-01 21:43:45.841 0 0 I init : processing action (ro.crypto.state=encrypted && ro.crypto.type=file && zygote-start) from (/system/etc/init/hw/init.rc:1090)
07-01 21:43:45.880 0 0 I init : starting service 'zygote'...
07-01 21:43:45.881 0 0 I init : Created socket '/dev/socket/zygote', mode 660, user 0, group 1000
07-01 21:43:46.329 282 282 D AndroidRuntime: >>>>>> START com.android.internal.os.ZygoteInit uid 0 <<<<<<
07-01 21:43:46.422 0 0 I init : service 'zygote' requested start, but it is already running (flags: 4)
07-01 21:43:46.527 282 282 I zygote64: option[0]=-Xzygote
07-01 21:43:47.411 282 282 D Zygote : begin preload
07-01 21:43:47.414 282 282 I Zygote : Calling ZygoteHooks.beginPreload()
07-01 21:43:47.523 282 282 V Zygote64Timing: BeginPreload took to complete: 112ms
07-01 21:43:47.524 282 282 I Zygote : Preloading classes...
07-01 21:43:47.745 283 283 V Zygote32Timing: PostZygoteInitGC took to complete: 330ms
07-01 21:43:47.745 283 283 V Zygote32Timing: ZygoteInit took to complete: 377ms
07-01 21:43:47.748 283 283 I Zygote : Accepting command socket connections
07-01 21:43:48.888 282 282 I Zygote : ...preloaded 17308 classes in 1364ms.
07-01 21:43:48.897 282 282 I Zygote : Preloading resources...
07-01 21:43:48.933 282 282 V Zygote64Timing: PreloadResources took to complete: 36ms
07-01 21:43:48.939 282 282 I Zygote : Preloading shared libraries...
07-01 21:43:48.942 282 282 I Zygote : Called ZygoteHooks.endPreload()
07-01 21:43:48.946 282 282 D Zygote : end preload
07-01 21:43:48.946 282 282 V Zygote64Timing: ZygotePreload took to complete: 1535ms
07-01 21:43:49.179 282 282 V Zygote64Timing: PostZygoteInitGC took to complete: 233ms
07-01 21:43:49.179 282 282 V Zygote64Timing: ZygoteInit took to complete: 1810ms
07-01 21:43:49.437 282 282 D Zygote : Forked child process 481
07-01 21:43:49.437 282 282 I Zygote : System server process 481 has been created
07-01 21:43:49.437 282 282 I Zygote : Accepting command socket connections
07-01 21:43:51.624 481 540 D SystemServerTimingAsync: InitThreadPoolExec:SecondaryZygotePreload
07-01 21:43:51.624 481 540 D SystemServerInitThreadPool: Started executing SecondaryZygotePreload
07-01 21:43:51.625 481 540 I SystemServer: SecondaryZygotePreload
07-01 21:43:51.627 283 283 I Zygote : Lazily preloading resources.
07-01 21:43:53.572 481 540 D SystemServerInitThreadPool: Finished executing SecondaryZygotePreload
07-01 21:43:54.078 282 282 I Zygote : Entering forkRepeatedly native zygote loop
07-01 21:43:54.081 282 282 D Zygote : Forked child process 690
结合日志与源码分析
通过上面日志看到,首先通过 init.zygote64.rc 启动 app_process64

那 app_process64 在哪呢,参见如下

# frameworks/base/cmds/app_process/Android.bp
cc_binary {name: "app_process",srcs: ["app_main.cpp"],
}
app_main.cpp 主函数如下
// frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]){AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// ...if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);}
}class AppRuntime : public AndroidRuntime { }// ./frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){// 启动虚拟机if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {return;}if (startReg(env) < 0) {ALOGE("Unable to register all android natives\n");return;}// ...// 启动 ./frameworks/base/core/java/com/android/internal/os/ZygoteInit.javajmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
}
//./framework/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {if (!enableLazyPreload) {// 加载资源 preload(bootTimingsTraceLog);}// ... // new ZygoteServer 构造中 通过 Zygote.createManagedSocketFromInitSocket 创建 LocalServerSocket zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);if (r != null) {r.run();return;}}// 创建 sokect server 等待连接caller = zygoteServer.runSelectLoop(abiList);
}
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {// ...pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);// ...
}
// ./framework/base/core/java/com/android/internal/os/Zygote.javastatic int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {ZygoteHooks.preFork();int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags, rlimits,permittedCapabilities, effectiveCapabilities);// Set the Java Language thread priority to the default value for new apps.Thread.currentThread().setPriority(Thread.NORM_PRIORITY);ZygoteHooks.postForkCommon();return pid;}
// framework/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(...){pid_t pid = zygote::ForkCommon(env, true,fds_to_close,fds_to_ignore,true);if (pid == 0) {// System server prcoess does not need data isolation so no need to// know pkg_data_info_list.SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,false, nullptr, nullptr, /* is_top_app= */ false,/* pkg_data_info_list */ nullptr,/* allowlisted_data_info_list */ nullptr, false, false);}
}
//./framework/base/core/jni/com_android_internal_os_Zygote.cpp
pid_t zygote::ForkCommon(...){pid_t pid = fork();if (pid == 0) {if (is_priority_fork) {setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);} else {setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);}}return pid;
}
systemServer zygote创建时序图
通过以上分析,SystemServer 创建对应时序图如下
若显示异常,可以查看图片 https://pic.chenjim.com/202407021035022.png-blog
一般应用 zygote 创建时序图
如果是 system server 以外的进程,会稍微有些不同,时序图如下
若显示异常,可以查看图片 https://pic.chenjim.com/202407022321535.png-blog
向 zygote socket 发送数据时序图
向 zygote socket server 发送数据的时序是怎样的呢,如下图所示
若显示异常,可以查看图片 https://pic.chenjim.com/202407031312243.png-blog
日志中 481 是 system server 进程,690 是 systemui 进程,后续会进一步分析相关流程
相关链接
- Git配置和常用命令
- 安卓软件开发常用命令集合
- adb常用命令详解–提升开发效率利器
- 安卓Framework开发快速分析日志及定位源码
相关文章:
安卓14中Zygote初始化流程及源码分析
文章目录 日志抓取结合日志与源码分析systemServer zygote创建时序图一般应用 zygote 创建时序图向 zygote socket 发送数据时序图 本文首发地址 https://h89.cn/archives/298.html 最新更新地址 https://gitee.com/chenjim/chenjimblog 本文主要结合日志和代码看安卓 14 中 Zy…...
等保一体机 | 什么是等保一体机?一台机器就能过等保吗?
什么是等保一体机? 对于中小型企业来说,他们在接触到等保的条件下,可能会觉得成本太高了,毕竟整改的时候,几台安全设备下来报价就几十w。 也许有些人会听说过等保一体机 那么什么是等保一体机呢? 等保一…...
【活动预告】Apache IoTDB TsFile 智慧能源应用“上会”啦!
2024 年,站在中国数字经济产业升级和数据要素市场化建设的时代交汇点上,为进一步推动全球数据库产业进步,由中国通信标准化协会、大数据技术标准推进委员会主办的“2024 可信数据库发展大会”将于 2024 年 7 月 16-17 日,在北京朝…...
【公益案例展】中国电信安全大模型——锻造安全行业能量转化的高性能引擎...
电信安全公益案例 本项目案例由电信安全投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2024中国数智产业最具社会责任感企业》榜单/奖项评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 以GPT系列为代表的大模型技术,展现了人工智能技术与应…...
CV07_深度学习模块之间的缝合教学(2)--维度转换
教学(1):链接 1.1 预备知识 问题:假如说我们使用的模型张量是三维的,但是我们要缝合的模块是四维的,应该怎么办? 方法:pytorch中常用的函数:(1)view函数(2…...
Oracle字符集修改
提示 Oracle数据库默认的字符集编码为US7ASCII,这个编码是不支持中文的,如果想要在数据库存储中文,就需要修改编码为ZHS16GBK或UTF-8 编码和字符集是一个意思,只是叫法不一样而已 前置条件 修改字符集的前提是知道我们现在用的是什…...
k8s核心操作_k8s中的存储抽象_基本概念与NFS搭建_Deployment使用NFS进行挂载---分布式云原生部署架构搭建028
然后我们继续开始看 如果我们使用容器部署,比如我们有三个节点,一个是master,一个node1 一个是node2 那么pod 中我们可以看到,容器中的 /data 等各个目录都映射了出来了,但是 如果比如上面红色的部分,有个pod,原来在node2上,最右边那个,但是这个pod宕机了 那么,k8s会在node…...
数学建模·熵权法
熵权法 一种计算评价指标之间权重的方法。熵权法是一种客观的方法,没有主观性,比较可靠。 具体定义 熵权法的核心在于计算信息熵,信息熵反映了一个信息的紊乱程度,体现了信息的可靠性 具体步骤 Step1正向化处理 将所以评价指标转…...
开放开源开先河(一)
2022年7月28日,以“软件定义世界 开源共筑未来”为主题的全球数字经济大会开放原子开源峰会在北京开幕,承办主峰会和为捐赠人进行授牌仪式的开放原子开源基金会再次进入公众视野。基金会秘书长孙文龙从汇聚全球产业链开源力量、核心链接能力、开发者分享…...
美团收银Android一面凉经(2024)
美团收银Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《美团收银Android一面凉经(2024)》。 应聘岗位: 美团餐饮PaaS平台Android开发工程师…...
触发器练习
在product表上创建三个触发器。每次激活触发器后,都会更新operate表。product表和 表的内容如下 Product表内容 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 产品编号 Int(10) 是 否 …...
Hadoop-25 Sqoop迁移 增量数据导入 CDC 变化数据捕获 差量同步数据 触发器 快照 日志
章节内容 上节我们完成了如下的内容: Sqoop MySQL迁移到HiveSqoop Hive迁移数据到MySQL编写脚本进行数据导入导出测试 背景介绍 这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学习。 之前已经在 VM 虚拟机…...
Facebook社交平台的未来发展趋势分析
随着科技和社交需求的不断演变,Facebook作为全球最大的社交平台之一,其未来发展的趋势备受关注。从技术创新到社会影响,Facebook正在经历着前所未有的变化和挑战。本文将探讨Facebook未来发展的几个关键趋势,并分析其可能的影响和…...
构建Memcached帝国:分布式部署策略与实践指南
构建Memcached帝国:分布式部署策略与实践指南 Memcached作为一个高性能的分布式内存缓存系统,在面对大规模分布式部署时,需要考虑一系列的策略和最佳实践来确保系统的稳定性和效率。本文将深入探讨Memcached分布式部署的注意事项,…...
Arcgis横向图例设置
想把这个图例改成横向的 点击图例的属性,找到样式...
26.7 Django单表操作
1. 模型管理器 1.1 Manager管理器 Django ORM中, 每个Django模型(Model)至少有一个管理器, 默认的管理器名称为objects. objects是一个非常重要的管理器(Manager)实例, 它提供了与数据库进行交互的接口.通过管理器, 可以执行数据库查询, 保存对象到数据库等操作.objects管理器…...
Android --- Kotlin学习之路:自己写一个SDK给别的APP用(暴漏一个接口,提供学生的身高数据)
今天又来肝kotlin了,主题是:用kt写一个SDK给其他人用,这个小技能在项目中会经常用到,应该有很多小伙伴还不会用,不会的请往下看—⬇ 在项目里面新建一个module 选择Android library,然后点击finish就行了 …...
租用海外服务器需要考虑哪些因素
当企业选择租用海外服务器时需要考虑到哪些因素呢? 对于海外服务器的租用我们需要考虑到机房的位置以及服务器的稳定性如何,所以企业可以选择离目标用户群体比较近一点的机房,以此来降低服务器的延迟度并且能够提高用户的访问速度。 对于机房…...
php将png转为jpg,可设置压缩率
/** * 将PNG文件转换为JPG文件 * param $pngFilePath string PNG文件路径 * param $jpgFilePath string JPG文件路径 * param $quality int JPG质量,0-100,值越低,压缩率越高 * return void * throws Exception */ function convertPngToJpg($pngFilePath, $jpgFile…...
华为HCIP Datacom H12-821 卷37
1.多选题 下面关于Network- Summary-LSA 描述正确的是 A、Network- Summary-LSA中的Metric被设置成从该ABR到达目的网段的开销值 B、Network- Sumary-LSA中的Net mask 被设置成目的网段的网络掩码 C、Network- Summary-LSA 是由ASBR产生的 D、Network- Summary-LSA 中的Li…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
