Android开发之热修复

#来自ウルトラマンゼロ(哉阿斯)

1 热修复核心

  • 资源修复
  • 代码修复
  • 动态链接库修复

2 资源修复

资源修复参考 Instant Run 的资源修复原理。

  • 创建 AssetManager,通过反射调用 addAssetPath 方法加载外部的的资源。
  • 将 AssetManager 类型的 mAssets 字段的引用全部替换成新创建的 AssetManager。

2.1 Instant Run

Instant Run 是 AS 2.0 新增的运行机制,其运行如下:

3 代码修复

代码修复主要有三个方案:

  • 类加载方案
  • 底层替换方案
  • Instant Run 方案

3.1 类加载方案

基于 Dex 分包方案

原理:

ClassLoad 加载类时候,调用 DexPatchList#findClass

public Class<?> findClass(String name, List<Throwable> suppressed) {
     for (Element element : dexElements) {
          Class<?> clazz = element.findClass(name, definingContext, suppressed);//查找类
         if (clazz != null) {
             return clazz;
         }
     }

     if (dexElementsSuppressedExceptions != null) {
         suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
     }
     return null;
}
  • Element 内部封装 DexFile,DexFile 用于加载 dex 文件,每个 dex 文件对应一个 Element;
  • 多个 Element 组成有序的数组 dexElements,查找类就是遍历这个数组;
  • Key.class 这个类有 bug,我们将 Key.class 修改之后,打一个新 dex 包 Patch.dex,放到 Element 数组的第一个,一旦查找到该类,后面那个有 bug 的 Key.class 就不会被加载从而达到修复 bug 的目的。

缺点:

  • 需要重启 App,不能即时生效,这是由于 App 运行时候,相关的类无法被卸载,需要重新启动 App。

Tinker原理:新旧包做 diff,比较生成一个 patch.dex,与手机中的 APK 的 classes.dex 做合并,生成一个新的 classes.dex,反射把这个 classes.dex 放到 Element 的第一个元素。

3.2 底层替换方案

直接在 Native 层修改原有类。替换 ArtMenthod 结构体中的字段或者整个 ArtMethod 结构体。

3.3 Instant Run 方案

Instant Run 在第一次构建 APK 会在每个方法中使用 AMS 注入类似的代码:

IncrementalChange localIncrementalChange = $change//类有修改,则不为空
if(localIncrementalChange != null){
     //执行修改类
      ...
}

4 动态链接库修复

主要应用 System 下面这两个方法:

  • System.load:参数是 so 在磁盘中的完整路径,加载指定路径的 so
  • System.loadLibrary:参数是 so 的名称,用于加载 App 安装后从 apk 包复制到 data/data/packagename/lib 目录下的 so 库

上面最后都调用 nativeLoad 这个 native 方法去加载so库, 这个方法的参数 fileName(so库在磁盘中的完整路径名)。最后调用 LoadNativeLibrary 函数加载类,方法和 类加载方案类似。

总结:

  • 将 so 补丁插入到 NativeLibraryElement 数组前部,让 so 补丁的路径先被返回和加载。
  • 调用 System 的 load 的方案来接管 so 的加载入口
  • 12
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值