热修复之AndFix探秘
热修复之AndFix探秘
近几年热修复技术可谓百花齐放,阿里的底层结构替换即时生效技术AndFix,后来又出来看起来很叼的Sophix,同时支持即时生效和冷启动修复。微信的Tinker和饿了么的Amigo。看了好几遍AndFix原理后,特写个Demo测试完成,写个博客记录下。
来张官网的原理图

首先模拟一个类中出现了BUG方法。

然后在布局文件点击事件中调用这个方法,程序不出意外的奔溃退出了。

然后我们在项目中引用andfix.so库

把AndFix类也加进来,因为最终通过这个类去调用so的修复方法。

增加一个注解类,用于标识要替换的类和方法。

现在在fixBug上面注解表示我要替换刚才那个有bug的方法。

这是AndFix调用修复的方法,只要我们把要有BUG的方法和修复好的BUG方法对象传进去就可以

现在的问题是修复好的方法怎么加载进来呢?
1通过DexClassLoader类加载器加载
DexClassLoader使用说明可参考https://blog.csdn.net/u011068702/article/details/53263442
[if !supportLists]2 [endif]通过DexFile类加载,DexFile加载使用比DexClassLoader要简单的多。本例子采用这种方法
通过DexClassLoader和BaseDexClassLoader的源码查看发现,DexClassLoader其实也是采用DexFile类的加载方法去加载的。而DexFile的加载方法是一个native方法。
由于android虚拟机不能直接加载java直接生成的class文件,所以借助dx工具把生成的class文件转换为dex文件
dx工具在相应的编译工具下,如下图所示我的dx工具目录

dx命令
dx --dex --output=classes2.dex com\example\hellojnicallback\JniHandler.class
要把JniHandler的包路径都复制过来,然后执行命令,执行成功后可以看到classes2.dex文件生成,把这个文件放到手机的sd卡上

然后加载,加载完后调用AndFix的替换方法,代码如下

在调用替换方法前记得调用AndFix的初始化方法

点击另一个按钮执行fixBug方法

输出如下

再点击按钮执行有bug的方法,

输出如下,没有崩溃了。证明方法已经替换成功了。
demo地址:https://github.com/helloworld777/hello-jni
AndFix github:https://github.com/alibaba/AndFix