热修复总结

305 阅读2分钟

代码热修复

  • 底层替换:限制颇多,立即见效。
  • 类加载:许冷启动才能见效,范围广,限制少。

底层替换方案

在已经加载了勒种直接替换原有的方法。无法实现对原有类方法和字段的增减,因为这样将破坏原有类的结构。

补丁类中出现了方法数的增加和减少,会导致整个Dex的方法数变化。方法数的变化伴随着方法索引的变化,这样在访问时就无法正常的索引到正确的方法。字段增加和减少和方法一样都会导致所有字段的索引都会发生变化。对于原先已经产生的类的实例,他们还会是原来的结构,而新方法方位新增字段就会产生不可预期的结果。

类加载方案

Tinker方案是完整的全量dex加载。

资源热修复

Instant Run 中的资源热修复:

构建一个新的AssertManager,通过反射调用它的addAssetPath方法把新push到设备上的改动资源的路径加进去,然后还是通过反射把当前所有使用中的AssertManager替换成这个新的,再重启就能找到修改后的资源。

阿里资源修复

构造一个package id 为0x66 的资源包,包里面只包含了改变了的资源。直接在原有的AssetManager中addAssetPath这个包就可以了。由于补丁包的package id为0x66,不与已经加载的0x7f冲突。

so库热修复

SO库修复本质上是对native方法的修复和替换。

我们采用类似类修复和反射注入方式。把补丁SO 库的路径插入到nativeLibraryDirectories数组的最前面,就能达到加载的使补丁SO库。

参考:

  • 深入探索Android热修复技术原理