什么是热修复
一般的bug修复都是等下一个版本解决,然后发布新的apk。
热修复可以直接在客户已经安装的程序当中修复bug。
bug一般出现在某个类某个方法,如果我们能够动态的将客户端apk里某个类替换成我们已经修改好的类。
流行技术
- QQ空间的超级补丁方案
- 微信的Tinker
- 阿里的AndFix、dexposed
- 美团的Robust、ele的migo、百度的hotfix
技术选型
- 我们的需求是什么,需求是恒量一切的标准
- 能满足需求的条件下,那个学习成本最低
- 学习成本一样的情况下,优先选择大公司的方案
AndFix
1.基本概念
https://github.com/alibaba/AndFix
AndFix只能完成方法的替换。
截止到写这篇博客时,AndFix最新版本0.5.0,支持Android2.3 to 7.0
2.集成与简单举例
- 添加依赖
1 | implementation 'com.alipay.euler:andfix:0.5.0@aar' |
- 例子代码
1 | package cn.gxh.myandfix; |
1 | package cn.gxh.myandfix; |
1 | package cn.gxh.myandfix; |
这里在MainActivity中有两个Button,一个是产生bug,一个是修复bug,bug代码在showStr方法中,我们先打一个有bug的签名apk,然后修改代码,再打一个修复后的签名apk。
1 | //修改后的代码,其它没变 |
- patch生成
1 | //命令说明 |
AndFix提供了生成补丁文件的工具,可在官网下载。这里我将修改前后两个apk以及签名文件都放在了同目录下,执行命令后生成的apatch文件在output文件夹下:
- 将apatch文件通过adb push到手机,由于机型不同以及本来路径就不同(这里我们在代码写死了)所以下面这个文件路径因人而异。
1 | adb push andfix.apatch /storage/emulated/0/Android/data/cn.gxh.myandfix/cache/apatch/ |
- 点击Button修复bug,经测试成功。
注意:实际使用中不可能通过adb push这种方式,也不可能让用户点击按钮操作修复bug。
3.将AndFix组件化
实际项目中,可以在Service中完成热修复。
1 | package cn.gxh.myandfix; |
1 | //可以在启动页中开启Service,当然不要忘了清单文件中注册 |
4.AndFix源码
通过上面的实践可以得知,主要的方法其实就几个
patchManager=new PatchManager(context);
patchManager.init(AppUtils.getAppVersionName(context));
patchManager.loadPatch();
首先实例化PatchManager对象,其实在PatchManager构造方法中初始化了一些变量:
1 | public PatchManager(Context context) { |
1 | public void init(String appVersion) { |
所以,不管是修复指定的补丁文件对应的bug,还是之前就存在的补丁文件对应的bug,都是把补丁文件封装成Patch对象,添加到集合mPatchs中,然后调用AndFixManager类的fix方法。
1 | public synchronized void fix(File file, ClassLoader classLoader, |
1 | private void fixClass(Class<?> clazz, ClassLoader classLoader) { |
之后就是调用native方法,会根据dalvik和art的不同,调用不同的方法处理。