Zygote在Framework中起什么作用?

news2024/11/17 18:26:03

前言

提到Zygote可能了解一些的小伙伴会说,它是分裂进程用的。没错它最大的作用的确是分裂进程,但是它除了分裂进程外还做了什么呢。还是老规矩,让我们抱着几个问题来看文章。最后在结尾,再对问题进行思考回复。

  1. 你能大概描述一遍Zygote的启动流程吗
  2. 我们为什么可以执行java代码,和zygote有什么关系
  3. Zygote到底都做了哪些事情

另外,我最近也看了一些写底层的文章。要么就是言简意赅到只知道Zygote的作用,但是完全不知道如何实现的,就像是背作文一样。要么是全篇都是代码,又臭又长,让人完全没有看下去的动力。

不过作为一个读者,太长的我可能完全不想看,太短的又真的完全就是被课文一点都不明白原理。

因此,本篇文章,仍旧会引入一些代码,方便大家通过代码方便记忆。但是又会将代码进行精简,以免给大家造成过度疲劳。我们的目的都是希望用最少的时间,能掌握更多的知识。

读源码时:不要过于纠结细节,不要过于纠结细节,不要过于纠结细节!重要的事情说三遍!!!

OK,让我们进入正题瞅瞅Zygote到底是个什么东西。


1.C++还是Java

选这个当标题当然是有原因的。我们知道的是Android系统启动的时候,运行的是Linux内核,执行的是C++代码。这是一个很有趣的事情。

因为我们在写App的时候,AndroidStudio默认给我们创建的都是Activity.java,而选择的语言,要么是Java要么就是Kotlin。

启动时候运行的是C++代码,应用层却可以使用Java代码,这到底是为什么呢?其实这就是Zygote的功劳之一。

2.Native层

Init进程创建Zygote时,会调用app_main.c的main() 方法。此时它依旧运行的是C++代码。我们通过下面的代码,来看下它到底做了什么。

这里它做的最关键的一件事就是启动AndroidRuntime(Android运行时)。,另外这里需要注意的是 start方法 中的 “com.android.internal.os.ZygoteInit” 这个类似于全类名。他到底是做什么的?别着急,大概2分钟后,你可能就会得到答案。

Zygote的新手村:app_main.cpp

int main(int argc, char* const argv[])
{
    //  创建Android运行时对象
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // 代码省略...
    
    // 调用AppRuntime.start方法,
    // 而AppRuntime是AndroidRuntime的子类,并且没有重写start方法
    // 因此调用的是AndroidRuntime的start方法
    runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}

精简后的代码告诉我们,这里一共就做了两件事,第一件创建AppRuntime,第二件调用start方法。

不过,AppRuntime是AndroidRuntime的子类,他没有重写start方法,因此这里调用的是 AndroidRuntime的start() 方法。

奇迹的诞生地:AndroidRuntime
这里我依旧只保留关键代码,源码关键注释也进行了保留。由下方代码看出这里做了三件改变命运的事情。

1.startVM – 启动Java虚拟机
2.startReg – 注册JNI
3.通过JNI调用Java方法,执行com.android.internal.os.ZygoteInit 的 main 方法

/*
 * Start the Android runtime. 
 */
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    /* start the virtual machine */
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
    }
}

有了JVM,注册了JNI,我们就可以执行Java代码了。

这里我个人建议不要过于纠结细节,比如JVM是如何创建的,JNI是如何注册的。如果感兴趣的童鞋,可以下载源码,到app_main.cpp里进行查看。这里就不进行赘述了。否则代码量太大,适得其反。

3.Java层

命运的十字路口:ZygoteInit.java:

之所以说是命运的十字路口,因为Zygote会在这里创建SystemServer,但是二者却走向了截然不同的道路。

从这里就开始执行Java代码了,当然这些Java代码是运行在JVM中的。

让我们通过代码来看一下,到底都做了些什么。
class ZygoteInit{

class ZygoteInit{

    /**
     * This is the entry point for a Zygote process.  It creates the Zygote server, loads resources,
     * and handles other tasks related to preparing the process for forking into applications.
     * This process is started with a nice value of -20 (highest priority).  
     */
     // 上面是源码中的注释,小伙伴们可以自行翻译一下。
     // 创建了ZygoteServer,加载资源,并且介绍了这个进程的优先级是最高的-20.
    public static void main(String argv[]) {
        ZygoteServer zygoteServer = null;

        // 1. 预加载资源,常用的:resource,class,library等在此处进行加载
        preload(bootTimingsTraceLog);
            
        // 2. 创建ZygoteServer,实际是一个Socket用来进行跨进程间通信用的。
        zygoteServer = new ZygoteServer(isPrimaryZygote);

        // 3. fork出SystemServer进程,这个进程会创建AMS,ATMS,WMS,电池服务等一切只有你想不到没有它做不到的服务
        forkSystemServer(abiList, zygoteSocketName, zygoteServer);

        // 4.里面是一个while(true)循环,等待接收AMS创建进程的消息,类似于handler中的Looper.loop()
        zygoteServer.runSelectLoop(abiList);
    }
}

上面代码里的注释基本说明了ZygoteInit都干了啥。下面会再稍微总结下:

  1. 创建了ZygoteServer:这是一个Socket相关的服务,目的是进行跨进程通信。
  2. 预加载preload:预加载相关的资源,
  3. 创建SystemServer进程:通过forkSystemServer分裂除了两个进程,一个Zygote进程,一个SystemServer进程。而且由于是分裂的,所以新分裂出来的进程也拥有虚拟机,也能调用JNI,也拥有预加载的资源,也会执行后续的代码。
  4. 执行runSelectLoop():内部是一个while(true)循环,等待AMS创建新的进程的消息。(想想Looper.loop())

4. 戛然而止

没错就是这么突然,Zygote的故事到这就结束了。至于它是如何创建SystemServer,如何去创建App那就是后面的故事了。所以你还记得我的问题嘛?我替你总结一下Zygote到底做了什么:

1.创建虚拟机
2.注册JNI
3.回调Java方法ZygoteInit.java 的main方法,从这儿开始运行Java代码
4.创建ZygoteServer,内部包含Socket用于跨进程通信
5.预加载class,resource,library等相关资源
6.fork 出了 SystemServer进程。他俩除了返回的pid不同,剩下一模一样。通过返回值不同来决定剩下的代码如何运行。这个留待后续进行讲解。
7.进入while(true)循环等待,等待AMS创建进程的消息(类似于Looper.loop())

5. 多说一句

这个系列才刚刚进行到第二章,我尽量让文章不是特别长的情况下,既有代码整理思路,又有总结方便记忆。代码是源码中摘抄的,省略了很大一部分,只能保证执行顺序。有兴趣的小伙伴可以下载源码进行查看。

其实最近我看了很多文章和视频,最后却选择写文章来对知识进行总结。归根结底就是因为一句话,好记性不如烂笔头。要是真的想快速记住,真的需要亲自查看一下源码。翻源码的同时,也是在不知不觉中锻炼你阅读源码的能力。 万一以后让你学习一个新的库,你也知道大概该怎么看。

都已经到这儿了,就稍微厚个脸皮,希望各位看官,能够点个赞,加个关注。毕竟一篇文章可能就要耗费几个小时的时间,上一篇文章就几个赞,感谢这几个小伙伴,让我有继续写下去的动力。 真心感谢你们。

另外,文章中有哪里出错,请及时指出。毕竟各位才是真正的大佬。希望各位Androider,可以一起取暖,度过这个互联网寒冬!加油各位!!!

6. Zygote功能图


根据上面简易的讲解了Zygote 进程,想问下大家对Framework 这块其他的知识点了解多少?为了帮助到大家更好的深入的料及Framework 底层知识点,小编整理了份Framework 核心知识点汇总手册,里面内容不仅有Binder,还有Handler、AMS、WMS、PMS等Framework底层内容的解析:https://0a.fit/acnLL

Framework 学习手册

1.Handler机制实现原理
2.Binder原理
3.Zygote部分
4.AMS源码分析
5.深入PMS源码
6.WMS

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

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

相关文章

【springboot进阶】使用aop + 注解方式,简单实现spring cache redis 功能

目录 一、实现思路 二、定义缓存注解 三、aop 切面处理 四、使用方式 五、灵活的运用 六、总结 前几天有同学看了 SpringBoot整合RedisTemplate配置多个redis库 这篇文章&#xff0c;提问spring cache 能不能也动态配置多个redis库。介于笔者没怎么接触过&#xff0c;所以…

【Graph】NetworkX官方基础教程

NetworkX官方基础教程图的基础知识1.1 图&#xff08;graph&#xff09;及其分类1.2 节点的度&#xff08;degree&#xff09;1.3 子图&#xff08;subgraph&#xff09;1.4 连通图1.5 图的矩阵表示NetworkX概述NetworkX基础教程1. 创建图2. 节点3. 边4. 清空图5. 图可视化6. 访…

基于javaweb框架的springboot mybatis宠物商城源码含论文设计文档

在互联网高速发展、信息技术步入人类生活的情况下&#xff0c;电子贸易也得到了空前发展。网购几乎成为了人人都会进行的活动。近几年来&#xff0c;养宠物更是成为人们生活中重要的娱乐内容之一&#xff0c; 人们越来越多的讲感情也寄托给了宠物&#xff0c;以给自己另一个感情…

自动驾驶--预测技术

根据百度技术培训中心课程整理( https://bit.baidu.com/productsBuy?id72) 背景简介 无人车系统从算法模块可分为三个部分&#xff0c;首先是感知通过对传感器数据和环境信息进行计算来解决周围有什么的问题&#xff0c;其次是预测&#xff0c;根据感知信息预测环境下一步将…

Java单元测试

1. 序言 1.1 工作中要求进行单元测试 毕业进入公司时&#xff0c;为了锻炼笔者的Java基础&#xff0c;老大给笔者分配了平台化开发的工作&#xff0c;基于Spring Boot Mybatis的Java Web后端开发一个人干后端开发&#xff0c;且以前也没有后端开发的经验&#xff0c;所以只是…

CTF之序列化__toString

序列化简介 本质上serialize()和unserialize&#xff08;&#xff09;在php内部的实现上是没有漏洞的&#xff0c;漏洞的主要产生是由于应用程序在处理对象&#xff0c;魔术函数以及序列化相关问题时导致的。 当传给unserialize()的参数可控时&#xff0c;那么用户就可以注入精…

【应用】Docker Swarm

Docker SwarmDocker Swarm 集群配置配置前准备初始化 SwarmSwarm 常用命令Portainer 集群管理Docker Swarm 集群配置 masternode1node2192.168.86.133192.168.86.131192.168.86.139 配置前准备 关闭各个节点服务器的防火墙 systemctl stop firewalld systemctl disable fire…

ATF问题二则:EL3可能没有实现吗? aarch32中的S-EL1是什么?

最近两个问题&#xff0c;戳到了我的知识盲点&#xff0c;当然我这个菜鸡ATF哪里都是盲点。 问题一&#xff1a;EL3可能没有实现吗&#xff1f; 问题二&#xff1a;bl2是aarch32, 那么bl2是S-EL1&#xff0c;bl31也是S-EL1? 1、EL3可能没有实现吗&#xff1f; The Armv8-A …

基于MATLAB的一级倒立摆控制仿真,带GUI界面操作显示倒立摆动画,控制器控制输出

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 一个可以活动的小车上立着一根不稳定随时会倒下的杆。小车的轮子由电机控制&#xff0c;可以控制小车电机的转动力矩M。同时&#xff0c;也可以获取小车轮子转动的圈数N&#xff08;可以精确到小…

java计算机毕业设计ssm实验室设备管理系统5k648(附源码、数据库)

java计算机毕业设计ssm实验室设备管理系统5k648&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xf…

162.基于Django-rest_framework的身份验证和权限

1. 概述 到目前为止&#xff0c;程序的API对任何人都可以编辑或删除&#xff0c;没有任何限制。我们希望有一些更高级的行为&#xff0c;进行身份验证和权限分配&#xff0c;以确保&#xff1a; 数据始终与创建者相关联只有经过身份验证的用户才能创建数据只有数据的创建者可…

嵌入式Linux上ifpulgd的使用配置与qemu模拟验证

问题引入 最近在项目开发中收到了一个非常简单的需求&#xff0c;我们的嵌入式Linux板卡需要在检测到网口插拔后重新配置网络&#xff0c;这在pc环境中非常常见。但是在这个项目的默认SDK中并没有相关配置&#xff0c;稍微查询了一下&#xff0c;在一般pc上通常使用Ifpulgd,并…

[附源码]Python计算机毕业设计Django企业售后服务管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【数据结构】树的概念与堆的实现

树的概念与堆的实现1、什么是树1.1 树的概念1.2 树的相关概念1.3 树的表示2、二叉树概念及结构2.1 概念2.2 特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储结构3、二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构3.3 堆的实现3.3.1 创建一个堆3.3.2 初始化堆3.3…

【计算机毕业设计】基于JSP的网上购物系统的设计与实现

分类号&#xff1a;TP315 U D C&#xff1a;D10621-408-(2007)5883-0 密 级&#xff1a;公 开 编 号&#xff1a;2003214012 学位论文 基于JSP的网上购物系统的设计与实现 基于JSP的网上购物系统的设计与实现 摘 要 近年来&#xff0c;随着Internet的迅速崛起&#xff0c…

内存 分页、交换空间

目录 1. 分页 1.1 地址转换 1.2 页表存在哪里 1.3 列表中究竟有什么 1.4 分页的优缺点 2. 快速地址转换&#xff08;TLB&#xff09; 2.1 TLB 的基本算法 2.2 谁来处理 TLB 未命中 2.2.1 硬件处理 2.2.2 软件&#xff08;操作系统&#xff09;处理 2.3 TLB 的内容 …

[附源码]Python计算机毕业设计SSM精准扶贫系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

(免费分享)基于springboot,vue公司财务系统

该系统是一个简单的公司财务管理系统&#xff0c;包含用户基本信息管理&#xff08;员工管理&#xff0c;管理员管理&#xff09;&#xff0c;工资管理&#xff08;员工工资管理&#xff0c;管理员工资管理&#xff09;&#xff0c;业务管理&#xff08;员工业务管理&#xff0…

Windows server 2012搭建用户隔离FTP站点

Windows server 2012搭建用户隔离FTP站点 系统添加FTP功能创建FTP登陆账户和其使用的文件夹D盘根目录下创建FTP站点主目录ftp文件夹ftp下创建用户主目录localuser&#xff08;名称不可更改&#xff0c;实现用户隔离必要步骤&#xff09;Localuser文件夹下创建对应用户的文件夹…

opencv入门笔记(二)

目录图像运算位运算位与运算位或运算取反运算异或运算位运算特点示例&#xff1a;位运算示例加法运算示例&#xff1a;查看三种加法运算的区别滤波器均值滤波中值滤波高斯滤波双边滤波示例&#xff1a;查看多种滤波器的处理效果视频处理示例&#xff1a;打开笔记本电脑内置摄像…