当前位置: 首页 > news >正文

安卓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 创建对应时序图如下

init.cpp init.zygote64.rc app_process.cpp AndroidRuntime.cpp ZygoteInit.java Zygote.java os_Zygote.cpp ZygoteServer.java LoadBootScripts service zygote start(...) startVm(...) startReg(...) main(...) preload(...) forkSystemServer(...) forkSystemServer(...) nativeForkSystemServer(...) zygote::ForkCommon(...) SpecializeCommon(...) new ZygoteServer(...) createManagedSocketFromInitSocket(...) runSelectLoop(...) init.cpp init.zygote64.rc app_process.cpp AndroidRuntime.cpp ZygoteInit.java Zygote.java os_Zygote.cpp ZygoteServer.java

若显示异常,可以查看图片 https://pic.chenjim.com/202407021035022.png-blog

一般应用 zygote 创建时序图

如果是 system server 以外的进程,会稍微有些不同,时序图如下

ZygoteServer.java ZygoteConnection.java Zygote.java ZygoteCommandBuffer.java ZygoteCommandBuffer.cpp os_Zygote.cpp runSelectLoop(...) processCommand(...) forkSimpleApps(...) forkRepeatedly(...) nativeForkRepeatedly(...) zygote::forkApp(...) zygote::ForkCommon(...) ZygoteServer.java ZygoteConnection.java Zygote.java ZygoteCommandBuffer.java ZygoteCommandBuffer.cpp os_Zygote.cpp

若显示异常,可以查看图片 https://pic.chenjim.com/202407022321535.png-blog

向 zygote socket 发送数据时序图

向 zygote socket server 发送数据的时序是怎样的呢,如下图所示

ActivityManagerService.java ProcessList.java Process.java ZygoteProcess.java startProcessLocked(...) startProcessLocked(...) handleProcessStart(...) startProcess(...) start(...) start(...) startViaZygote(...) zygoteSendArgsAndGetResult(...) attemptZygoteSendArgsAndGetResult(...) ActivityManagerService.java ProcessList.java Process.java ZygoteProcess.java

若显示异常,可以查看图片 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…...

等保一体机 | 什么是等保一体机?一台机器就能过等保吗?

什么是等保一体机&#xff1f; 对于中小型企业来说&#xff0c;他们在接触到等保的条件下&#xff0c;可能会觉得成本太高了&#xff0c;毕竟整改的时候&#xff0c;几台安全设备下来报价就几十w。 也许有些人会听说过等保一体机 那么什么是等保一体机呢&#xff1f; 等保一…...

【活动预告】Apache IoTDB TsFile 智慧能源应用“上会”啦!

2024 年&#xff0c;站在中国数字经济产业升级和数据要素市场化建设的时代交汇点上&#xff0c;为进一步推动全球数据库产业进步&#xff0c;由中国通信标准化协会、大数据技术标准推进委员会主办的“2024 可信数据库发展大会”将于 2024 年 7 月 16-17 日&#xff0c;在北京朝…...

【公益案例展】中国电信安全大模型——锻造安全行业能量转化的高性能引擎...

‍ 电信安全公益案例 本项目案例由电信安全投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2024中国数智产业最具社会责任感企业》榜单/奖项评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 以GPT系列为代表的大模型技术&#xff0c;展现了人工智能技术与应…...

CV07_深度学习模块之间的缝合教学(2)--维度转换

教学&#xff08;1&#xff09;&#xff1a;链接 1.1 预备知识 问题&#xff1a;假如说我们使用的模型张量是三维的&#xff0c;但是我们要缝合的模块是四维的&#xff0c;应该怎么办&#xff1f; 方法&#xff1a;pytorch中常用的函数&#xff1a;(1)view函数&#xff08;2…...

Oracle字符集修改

提示 Oracle数据库默认的字符集编码为US7ASCII&#xff0c;这个编码是不支持中文的&#xff0c;如果想要在数据库存储中文&#xff0c;就需要修改编码为ZHS16GBK或UTF-8 编码和字符集是一个意思&#xff0c;只是叫法不一样而已 前置条件 修改字符集的前提是知道我们现在用的是什…...

k8s核心操作_k8s中的存储抽象_基本概念与NFS搭建_Deployment使用NFS进行挂载---分布式云原生部署架构搭建028

然后我们继续开始看 如果我们使用容器部署,比如我们有三个节点,一个是master,一个node1 一个是node2 那么pod 中我们可以看到,容器中的 /data 等各个目录都映射了出来了,但是 如果比如上面红色的部分,有个pod,原来在node2上,最右边那个,但是这个pod宕机了 那么,k8s会在node…...

数学建模·熵权法

熵权法 一种计算评价指标之间权重的方法。熵权法是一种客观的方法&#xff0c;没有主观性&#xff0c;比较可靠。 具体定义 熵权法的核心在于计算信息熵&#xff0c;信息熵反映了一个信息的紊乱程度&#xff0c;体现了信息的可靠性 具体步骤 Step1正向化处理 将所以评价指标转…...

开放开源开先河(一)

2022年7月28日&#xff0c;以“软件定义世界 开源共筑未来”为主题的全球数字经济大会开放原子开源峰会在北京开幕&#xff0c;承办主峰会和为捐赠人进行授牌仪式的开放原子开源基金会再次进入公众视野。基金会秘书长孙文龙从汇聚全球产业链开源力量、核心链接能力、开发者分享…...

美团收银Android一面凉经(2024)

美团收银Android一面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《美团收银Android一面凉经(2024)》。 应聘岗位: 美团餐饮PaaS平台Android开发工程师…...

触发器练习

在product表上创建三个触发器。每次激活触发器后&#xff0c;都会更新operate表。product表和 表的内容如下 Product表内容 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 产品编号 Int(10) 是 否 …...

Hadoop-25 Sqoop迁移 增量数据导入 CDC 变化数据捕获 差量同步数据 触发器 快照 日志

章节内容 上节我们完成了如下的内容&#xff1a; Sqoop MySQL迁移到HiveSqoop Hive迁移数据到MySQL编写脚本进行数据导入导出测试 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机…...

Facebook社交平台的未来发展趋势分析

随着科技和社交需求的不断演变&#xff0c;Facebook作为全球最大的社交平台之一&#xff0c;其未来发展的趋势备受关注。从技术创新到社会影响&#xff0c;Facebook正在经历着前所未有的变化和挑战。本文将探讨Facebook未来发展的几个关键趋势&#xff0c;并分析其可能的影响和…...

构建Memcached帝国:分布式部署策略与实践指南

构建Memcached帝国&#xff1a;分布式部署策略与实践指南 Memcached作为一个高性能的分布式内存缓存系统&#xff0c;在面对大规模分布式部署时&#xff0c;需要考虑一系列的策略和最佳实践来确保系统的稳定性和效率。本文将深入探讨Memcached分布式部署的注意事项&#xff0c…...

Arcgis横向图例设置

想把这个图例改成横向的 点击图例的属性&#xff0c;找到样式...

26.7 Django单表操作

1. 模型管理器 1.1 Manager管理器 Django ORM中, 每个Django模型(Model)至少有一个管理器, 默认的管理器名称为objects. objects是一个非常重要的管理器(Manager)实例, 它提供了与数据库进行交互的接口.通过管理器, 可以执行数据库查询, 保存对象到数据库等操作.objects管理器…...

Android --- Kotlin学习之路:自己写一个SDK给别的APP用(暴漏一个接口,提供学生的身高数据)

今天又来肝kotlin了&#xff0c;主题是&#xff1a;用kt写一个SDK给其他人用&#xff0c;这个小技能在项目中会经常用到&#xff0c;应该有很多小伙伴还不会用&#xff0c;不会的请往下看—⬇ 在项目里面新建一个module 选择Android library&#xff0c;然后点击finish就行了 …...

租用海外服务器需要考虑哪些因素

当企业选择租用海外服务器时需要考虑到哪些因素呢&#xff1f; 对于海外服务器的租用我们需要考虑到机房的位置以及服务器的稳定性如何&#xff0c;所以企业可以选择离目标用户群体比较近一点的机房&#xff0c;以此来降低服务器的延迟度并且能够提高用户的访问速度。 对于机房…...

php将png转为jpg,可设置压缩率

/** * 将PNG文件转换为JPG文件 * param $pngFilePath string PNG文件路径 * param $jpgFilePath string JPG文件路径 * param $quality int JPG质量,0-100,值越低&#xff0c;压缩率越高 * 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…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...