news 2026/4/16 4:57:32

编译(二):class、dex、so 编译流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
编译(二):class、dex、so 编译流程

编译(一):理论知识

编译(二):class、dex、so 编译流程


Class 流程

  • 加载:查找和导入类的二进制数据
  • 链接:执行验证,准备和(可选)解析
    • 验证:确保导入类型的正确性
    • 准备:为类变量分配内存并将内存初始化为默认值
    • 解析:将符号引用从类型转换为直接引用。
  • 初始化:调用将代码初始化为正确的初始值的Java代码。
  • 加载:将类的信息从文件中获取并且载入到JVM内存中
    1. 通过一个类的全限定名来获取其定义的二进制字节流
    2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
    3. 在Java堆中生成一个代表这个类的 java. lang Class对象,作为对方法区中这些数据的访问入口
  • 验证:检查读入的结构是否符合JVM规范的描述
    1. 为了确保 Class文件中的字节流包含的信息符合当前虚拟机的要求
    2. 文件格式的验证、元数据的验证、字节码验证和符号引用验证
  • 准备:分配内存,初始化变量
  • 解析:把这个类的常量池的所有符号引用改变成直接引用
  • 初始化:执行静态初始化程序、类构造器方法的过程

PathClassLoader 流程

  • 初始化
  • DexPathList.DexPathList
    • dexElements: 根据多路径的分隔符“;”将dexPath转换成File列表,记录所有的dexFile
    • nativeLibraryPathElements: 记录所有的Native动态库, 包括app目录的native库和系统目录的native库。
    • makePathElements
    • makeDexElements 创建Element数组
    • loadDexFile
    • 创建对象DexFile
    • openDexFile
    • dalvik_system_DexFile.DexFile_openDexFileNative
  • ClassLoader.loadClass
    • 判断当前类加载器是否已经加载过指定类,若已加载则直接返回,否则继续执行;
    • 调用parent的类加载递归加载该类,检测是否加载,若已加载则直接返回,否则继续执行;
    • 调用当前类加载器,通过findClass加载。
  • findClass
  • DexPathList.findClass 一个Classloader可以包含多个dex文件,每个dex文件被封装到一个Element对象,这些Element对象排列成有序的数组 dexElements。当查找某个类时,会遍历所有的dex文件,如果找到则直接返回,不再继续遍历dexElements。
  • DexFile.loadClassBinaryName
  • dalvik_system_DexFile.defineClassNative 在native层创建目标类的对象并添加到虚拟机列表

System.loadLibrary 流程

  • System.loadLibrary
  • Runtime.loadLibrary
    • 当loader不为空时, 则通过loader.findLibrary()查看目标库所在路径;
    • 当loader为空时, 则从默认目录mLibPaths下来查找是否存在该动态库;
      • System.initUnchangeableSystemProperties 将大量的key-value对保存到Properties对象, 重点看specialProperties
      • System.parsePropertyAssignments 将assignments数据解析后保存到Properties对象,而此处的assignments来源于java_lang_System.specialProperties()方法
      • linker.do_android_get_LD_LIBRARY_PATH 看kDefaultLdPaths数组
      • linker.kDefaultLdPaths
  • BaseDexClassLoader.findLibrary
    • DexPathList.DexPathList DexPathList初始化
      • dexElements: 记录所有的dexFile文件
      • nativeLibraryPathElements: 记录所有的Native动态库, 包括app目录的native库和系统目录的native库.
    • DexPathList.findLibrary 从所有的动态库nativeLibraryPathElements(包含两个系统路径)查询是否存在匹配的
    • System.mapLibraryName 将动态库的名字转换为so
    • DexPathList.java ::Element.findNativeLibrary 遍历查询,一旦找到则返回所找到的目标动态库
  • Runtime.doLoad 增加同步锁,保证并发时一致性
    • 当loader为空,则ldLibraryPath为系统目录下的Native库
    • 当lodder不为空,则ldLibraryPath为app目录下的native库
    • java_lang_Runtime.Runtime_nativeLoad
      • 调用dlopen函数,打开一个so文件并创建一个handle;
      • 调用dlsym()函数,查看相应so文件的JNI_OnLoad()函数指针,并执行相应函数。
  • android_media_MediaPlayer.JNI_OnLoad
  • android_media_MediaPlayer.register_android_media_MediaPlayer
  • AndroidRuntime.registerNativeMethods
  • JNIHelp.jniRegisterNativeMethods
  • jni.RegisterNatives 这个过程完成了gMethods数组中的方法的映射关系
  • java_vm_ext.LoadNativeLibrary
    • JavaVM:进程虚拟机环境,每个进程有且只有一个JavaVM实例
    • JNIEnv:线程上下文环境,每个线程有且只有一个JNIEnv实例
    • 检查该动态库是否已加载
    • 通过dlopen打开动态共享库
    • 创建SharedLibrary共享库,并添加到libraries_列表
    • 通过dlsym获取JNI_OnLoad符号所对应的方法, 并调用该方法
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/9 2:07:00

【好写作AI】别慌!“AI痕迹”检测,到底在检测什么?

好写作AI官方网址:https://www.haoxiezuo.cn/一、新的焦虑正在蔓延:你的论文,有“AI味”吗? 提交论文前,除了查重,你是不是开始多了一个动作——把文段丢进各种“AI检测器”,紧张地等待结果&…

作者头像 李华
网站建设 2026/4/14 16:32:22

制造工厂研发人员需要实现5个SolidWorks共享一台服务器如何实现

在制造工厂中,当5名SolidWorks研发人员需要共享一台服务器时,合理的配置和优化能够显著提升协作效率和数据安全性。此方案核心在于集中化资源管理、动态化资源分配、智能化权限管控,结合高性能硬件配置与协同设计功能,可显著提升资…

作者头像 李华
网站建设 2026/4/13 14:08:46

数据不会说话?虎贲等考 AI 数据分析:让论文实证硬核到惊艳导师

还在对着一堆问卷数据、实验结果抓耳挠腮?用 SPSS 半天跑不出一个相关性分析,用 Excel 画的图表被批 “小学生水平”?辛苦收集的数据,最后只能用干巴巴的文字描述,论文实证部分毫无说服力? 在论文写作的实…

作者头像 李华
网站建设 2026/4/11 0:18:08

打破“数据孤岛”,实现全厂设备一站式可视化管理

核心痛点:在传统的制造工厂中,不同品牌、不同型号的PLC(西门子、三菱、欧姆龙等)控制着生产线上的各类设备。这些设备数据相互隔绝,形成一个个“数据孤岛”。管理者无法实时掌握设备运行状态、工艺参数、故障信息&…

作者头像 李华
网站建设 2026/4/13 19:24:42

Python+Vue的线上社区信息发布管理平台设计 Pycharm django flask

收藏关注不迷路!!需要的小伙伴可以发链接或者截图给我 项目介绍 随着互联网技术的不断发展,线上社区已经成为了人们日常生活中不可或缺的一部分。在这样的背景下,为了更好地服务社区用户,提高信息传递的效率和准确性&a…

作者头像 李华