安卓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…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
