安卓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开发快速分析日志及定位源码

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

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

相关文章

HarmonyOS ArkUi 字符串<展开/收起>功能

效果图&#xff1a; 官方API&#xff1a; ohos.measure (文本计算) 方式一 measure.measureTextSize 跟方式二使用一样&#xff0c;只是API调用不同&#xff0c;可仔细查看官网方式二 API 12 import { display, promptAction } from kit.ArkUI import { MeasureUtils } fr…

基于蓝牙iBeacon定位技术的商场3D楼层导视软件功能详解与实施效益

在现代商场的繁华与复杂中&#xff0c;寻找目的地往往令人头疼。维小帮3D楼层导视软件以其创新技术&#xff0c;为顾客带来无缝、直观的跨楼层导航体验&#xff0c;让每一次商场消费都成为享受。 商场3D楼层导视软件功能服务 3D多楼层导视地图&#xff0c;商场布局一览无遗 …

【Go】函数的使用

目录 函数返回多个值 init函数和import init函数 main函数 函数的参数 值传递 引用传递&#xff08;指针&#xff09; 函数返回多个值 用法如下&#xff1a; package mainimport ("fmt""strconv" )// 返回多个返回值&#xff0c;无参数名 func Mu…

计网-三次握手和四次挥手

TCP建立和断开连接的过程&#xff08;三次握手和四次挥手&#xff09; TCP通信的过程&#xff1a; 问题&#xff1a;tcp是如何保证数据在客户端和服务端之间通信传输的&#xff1f; 分为三个步骤&#xff1a;三次握手&#xff0c;传输数据确认&#xff0c;四次挥手。三次握手…

Python | Leetcode Python题解之第232题用栈实现队列

题目&#xff1a; 题解&#xff1a; class MyQueue:def __init__(self):self.A, self.B [], []def push(self, x: int) -> None:self.A.append(x)def pop(self) -> int:peek self.peek()self.B.pop()return peekdef peek(self) -> int:if self.B: return self.B[-1…

如何找回误删的文件?4个常用文件恢复方法!

对于许多用户来说&#xff0c;误删文件是一种常见而令人懊恼的情况。恢复误删文件的重要性在于&#xff0c;它可以帮助用户找回宝贵的数据&#xff0c;避免因数据丢失带来的各种不便和损失。 如何找回不小心删除的文件&#xff1f; 误删数据不知道怎么恢复&#xff0c;会给我…

OS Copilot:新手测评体验

文章目录 前言一、OS Copilot&#xff08;阿里云操作系统智能助手&#xff09;简介二、测评体验总结OS Copilot 产品体验评测OS Copilot 产品功能反馈 前言 本文简单分享一下自己使用OS Copilot测评体验。 一、OS Copilot&#xff08;阿里云操作系统智能助手&#xff09;简介 …

一个极简的 Vue 示例

https://andi.cn/page/621516.html

【BUG】已解决:JsonMappingException

已解决&#xff1a;JsonMappingException 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 概述&#xff1a; 没有getter方法的实体的序列化&#xff0c;并解决Jackson引发的JsonMappingException异常。 默认情况下&#xff0c;Jackson 2只会处理公有字段或具有公有get…

vue 自定义滚动条同步拖动(移动端)

实现效果&#xff0c;拖动左右箭头实现图片区域同步滚动&#xff0c;到边缘停止拖动。 HTML代码 <template><div touchstart"onClick"><!--使用draggable组件 图片列表区域--><draggablev-model"select_list"end"onEnd"cl…

比赛获奖的武林秘籍:06 5 分钟速通比赛路演答辩,国奖选手的血泪经验!

比赛获奖的武林秘籍&#xff1a;06 5 分钟速通比赛路演答辩&#xff0c;国奖选手的血泪经验&#xff01; 摘要 本文主要介绍了大学生电子计算机类比赛和创新创业类比赛常见雷点、要点和精髓&#xff0c;并对路演的定义和基本概念进行了说明&#xff0c;结合自身经历对路演答辩…

【提交ACM出版 | EIScopus检索稳定 | 高录用】第五届大数据与社会科学国际学术会议(ICBDSS 2024,8月16-18)

第五届大数据与社会科学国际学术会议&#xff08;ICBDSS 2024&#xff09;将于2024年08月16-18日在中国-上海隆重举行。 ICBDSS会议在各专家教授的支持下&#xff0c;去年已成功举办了四届会议。为了让更多的学者有机会参与会议分享交流经验。本次会议主要围绕“大数据”、“社…

Python酷库之旅-第三方库Pandas(020)

目录 一、用法精讲 49、pandas.merge_asof函数 49-1、语法 49-2、参数 49-3、功能 49-4、返回值 49-5、说明 49-5-1、功能 49-6、用法 49-6-1、数据准备 49-6-2、代码示例 49-6-3、结果输出 50、pandas.concat函数 50-1、语法 50-2、参数 50-3、功能 50-4、返…

小米起诉“小米”商标侵权,索赔500万!

近日浙江丽水有家叫小米的公司&#xff0c;因为商标侵权被小米科技起诉索赔500万&#xff0c;需要变更企业名称&#xff0c;官网也不能用“小米智能大家居”等&#xff0c;还有其它的赔偿&#xff0c;普推知产商标老杨分析&#xff0c;“小米智能大家居”“小米”&#xff0c;后…

ensp防火墙综合实验作业+实验报告

实验目的要求及拓扑图&#xff1a; 我的拓扑&#xff1a; 更改防火墙和交换机&#xff1a; [USG6000V1-GigabitEthernet0/0/0]ip address 192.168.110.5 24 [USG6000V1-GigabitEthernet0/0/0]service-manage all permit [Huawei]vlan batch 10 20 [Huawei]int g0/0/2 [Huawei-…

深入探讨【C++容器适配器】:现代编程中的【Stack与Queue】的实现

目录 一、Stack&#xff08;栈&#xff09; 1.1 Stack的介绍 1.2 Stack的使用 1.3 Stack的模拟实现 二、Queue&#xff08;队列&#xff09; 2.1 Queue的介绍 2.2 Queue的使用 2.3 Queue的模拟实现 三、容器适配器 3.1 什么是适配器 3.2 为什么选择deque作为stack和…

Apache Flink核心特性应用场景

Flink的定义 Apache Flink是一个分布式处理引擎&#xff0c;用于处理 无边界数据流&#xff0c; 有边界数据流上金秀贤有状态的计算。Flink能在所有常见的集群环境中运行&#xff0c;并能以内存速度和任意规模进行计算如下Flink官网的一张图 Flink 与Spark的区别 Flink 中处…

5.SpringBoot核心源码-启动类源码分析

目录 概述技巧spring boot 如何启动应用程序run方法里面核心逻辑 SpringApplicaiton.run(xxx.class,args)结束 概述 SpringBoot核心源码-启动类源码分析 技巧 如何给外部源码加注释&#xff0c;想要在源码中添加自己的注释&#xff0c;会弹出 file is read only&#xff0c;代…

【多媒体】Java实现MP4和MP3音视频播放器【JavaFX】【更多功能的播放器】【音视频播放】

在Java中播放视频可以使用多种方案&#xff0c;最常见的是通过Swing组件JFrame和JLabel来嵌入JMF(Java Media Framework)或Xuggler。不过&#xff0c;JMF已经不再被推荐使用&#xff0c;而Xuggler是基于DirectX的&#xff0c;不适用于跨平台。而且上述方案都需要使用第三方库。…

GD32MCU最小系统构成条件

大家是否有这个疑惑&#xff1a;大学课程学习51的时候&#xff0c;老师告诉我们51的最小系统构成&#xff1f;那么进入32位单片机时代&#xff0c;gd32最小系统构成又是怎么样的呢&#xff1f; 1.供电电路 需要确保供电的电压电流稳定&#xff0c;以东方红开发版为例&#xff…