热修复学习笔记(一)

30 篇文章 0 订阅

1. 为什么需要热修复?

image-20201118164408654

此外,如果有一些紧急需要上线的小需求,希望马上能上线的,也可以借助热修复快速迭代,当然也不能过于依赖热修复。

因此总结一下,它有几大优势

(1)不依赖发版。

(2)用户无感知,无需下载最新应用。

(3)修复成功率高,能快速把损失降到最低。

2. 热修复的原理

修复可以分成三种目标,分别是代码修复、资源修复以及so库修复。

代码修复是我们最经常使用的场景。代码修复又可以分为三种解决方案底层替换方案、类加载方案和Instant Run方案。

2.1类加载方案

类加载方案,基于dex分包方案,具体原理这里还没有进一步学习,大致就是一个dex文件(这个在后面再介绍什么是dex文件)能加载的最大方法数有上限,最多65536个,而一个app随着功能的增加,很可能会超过限制,因此出现了dex分包方案。也就是将一个应用分成多个dex文件,将应用启动必须所需的类放在主dex中,当应用启动时先加载主Dex,再动态的加载次Dex,从而缓解了主Dex的65536限制。基于这个原理,因此有了可以操作的空间。

类加载方案而用很简单的话来说就是,让app加载我们修复好的类,而不是之前出bug的类,自然就能修复bug了。

由于Android虚拟机的是Dalvik ,并不是标准的java虚拟机,而在java虚拟机中通常是将.class文件加载就行了。而在Android 中 加载顺序是 .java->.class->.dex ,dex文件才是最终能被Dalvik执行的文件。

Android 中的类加载器是DexClassLoader和PathClassLoader而不是java中的三个系统加载器,这两者的区别在于PathClassLoader只能加载dex文件或者是已经安装的apk文件(已经安装的apk里面包含了已经解压好的dex文件),而不能从zip中解压出dex文件,而DexClassLoader可以支持.apk、.jar、.dex文件。

当虚拟机在加载时,会遍历一个存放所有dex文件的集合,按照一定的顺序进行加载。当一个类的dex文件被加载后,后面的dex文件如果还有的这个类就不会被执行了。因此我们的热修的原理也很简单,就是把修复好的dex文件放在有bug的dex文件之前,这样就能实现基于类级别的修复,也就是插桩热修的方式。如下图所示

image-20201202185558136

这种方案是不能及时生效的,需要app重启,重新加载dex文件。

2.2底层替换方案

和类加载方法不同的是,不会重新加载新类,而是直接native层修改原有类。这种方式限制较多,不能增减原有类的方法和字段,这样子会改变方法和字段的索引数,导致无法找到正确的方法。因此只能够替换方法。

通过反射找到方法对应的artMethod指针,这个指针所指向的结构体包含了java方法的所有信息比如入口、所属类等等。因此想要替换执行的方法,只需要修改artMethod指针就可以将bug的方法不执行,而去执行修复的方法。

整体的修复流程如下所示。

image-20201204110823864

AndFix是只替换ArtMethod结构体中的字段,这样会有兼容问题,因为厂商可能会修改ArtMethod结构体,导致方法替换失败。

而我们所使用的Sophix采用的是替换整个ArtMethod结构体,这样不会存在兼容问题。

2.3 Instant Run

分为三种热插拔(Hot Swap)、温插拔(Warm Swap)、冷插拔(Cold Swap)。三种的区别在于热插拔只针对方法内逻辑的修改,温插拔适合资源的增减,需要重启当前activity生效,冷插拔一般主要针对类结构改变。

在ASM构建apk的时候,会为每个方法注入一个change的字段。如果change为空,就执行原有逻辑,如果不为空,就会执行新的被替换的类中修改的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值