返回

Android热修复Tinker源码分析(二)——补丁包的合成

Android

Tinker:深入解析 Android 热修复神器中的补丁包合成

Dex 合成概述

Android 热修复神器 Tinker 在补丁包合成过程中,会经历以下步骤:

  • 提取代码变更信息: Tinker 从补丁差异文件中提取需要修改的代码信息。
  • 生成 Dex 补丁文件: Tinker 使用 ASM 框架生成包含修改类和方法的 Dex 补丁文件。
  • 合并 Dex 文件: Tinker 将原始 Dex 文件与 Dex 补丁文件合并成一个新文件。
  • 优化合并后的 Dex 文件: Tinker 优化新文件以减小体积并提升性能。

Dex 加载机制

Dex(Dalvik Executable)是一种专为 Android 虚拟机设计的可执行文件格式,它将 Java 字节码编译成一种优化格式。Dex 文件的加载过程包括:

  • 加载 Dex 文件: DexClassLoader 类加载 Dex 文件并将其映射到内存。
  • 验证 Dex 文件: 系统验证文件格式并检查是否存在恶意代码。
  • 准备 Dex 文件: 系统解析类信息和构建类层次结构。
  • 解析 Dex 文件: 系统解析 Dex 文件并将类信息加载到内存。

Art 编译机制

Android 5.0 中引入了 Art 运行时,它取代了 Dalvik 虚拟机并使用了 Ahead-of-Time (AOT) 编译器。Art 在安装应用程序时将 Dex 文件编译成机器码:

  • 类加载: Art 加载 Dex 文件并解析类信息。
  • 识别方法: Art 识别需要编译的方法,包括 native 方法。
  • 编译方法: Art 使用即时编译器 (JIT) 将方法编译成机器码。
  • 执行方法: 机器码直接被 CPU 执行。

Dex 合成过程

Tinker 将原始 Dex 文件和 Dex 补丁文件合并成一个新文件:

  1. 加载 Dex 文件: Tinker 使用 DexClassLoader 加载原始 Dex 文件。
  2. 加载补丁文件: Tinker 加载 Dex 补丁文件并提取补丁信息。
  3. 合并类信息: Tinker 将原始 Dex 文件和 Dex 补丁文件中的类信息合并。
  4. 生成新 Dex 文件: Tinker 使用 DexWriter 类生成一个包含合并类信息的新 Dex 文件。
  5. 优化新 Dex 文件: Tinker 使用 Proguard 等工具优化文件大小和性能。

优化技巧

Tinker 提供优化技巧以提高合成效率和减小补丁包大小:

  • 增量编译: Tinker 仅编译受影响的方法,而不是整个应用程序。
  • 共享类库: Tinker 将不变的类和方法提取到一个共享类库中。
  • DexDiff 算法: Tinker 使用 DexDiff 算法计算需要修改的 Dex 字节码范围。
  • 并行合成: Tinker 支持并行合成多个 Dex 文件。

总结

Tinker 使用 Dex 合成来创建补丁包,通过增量编译和优化技巧提高效率。这种方法确保了快速、无缝的热修复。

常见问题解答

  1. Tinker 如何确定需要修改的代码?
    通过分析补丁差异文件中的代码变更信息。

  2. 为什么使用 Dex 补丁文件?
    Dex 补丁文件只包含需要修改的代码,从而减小补丁包大小。

  3. 优化合并后的 Dex 文件有哪些好处?
    优化后,文件体积更小,性能更高。

  4. Tinker 如何处理 Art 编译?
    Tinker 生成的新 Dex 文件可以被 Art 编译为机器码。

  5. 增量编译和共享类库如何提高效率?
    它们只合成受影响的代码,并避免重复合成不变的类和方法。