什么是热修复呢?
热修复是针对修复app中的bug的场景来定义的。
假设,现在用户使用的app有个方法报错了,那么解决这个问题,目前有2种方式:
一:直接下载整个最新app重新安装;二:使用增量更新的方式下载patch包合成新apk,重新安装;
虽然增量更新的体验更好,但是这2种方式的共同问题是都需要重新安装。那么,有没有一种方式不用重新安装app,在用户不知不觉中就修复了bug呢?
热修复技术就是在不重新安装app的前提下,通过下载patch包,动态加载到内存替换有bug的方法,从而实现修复bug。
热修复的实现原理
首先,生成新版本和旧版本的差异补丁包文件(此步骤有点类似于增量更新的第一步);
其次,使用热修复框架的Api在Application中去尝试加载指定路径的补丁差异包;
最后,只需要将补丁包文件拷贝到对应路径,打开有bug的App,在Application创建的时候就已经将补丁包文件加载到内存中并且替换了对应的方法。
不知不觉中,bug已然修复。
阿里的热修复框架AndFix
热修复有很多方案,其中阿里开源的AndFix使用起来比较简单,而且比较稳定。
详情查看github地址:https://github.com/alibaba/AndFix
阿里的AndFix框架使用步骤如下:
首先,创建一个app,模拟出bug程序:
public void show(View v){
Cat cat = new Cat();
Toast.makeText(this, cat.getName(), Toast.LENGTH_SHORT).show();
}
然后,在gradle中依赖AndFix类库,并且在Application的onCreate方法中编写出加载patch文件的代码:
//经反复测试,0.5的版本不如0.4的版本稳定,因此我们用稳定的版本
//compile 'com.alipay.euler:andfix:0.5.0@aar'
compile 'com.alipay.euler:andfix:0.5.0@aar'
添加加载patch文件的代码:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
PatchManager patchManager = new PatchManager(this);
String appVersion = "1.0";//当前app的版本号
patchManager.init(appVersion);
//开始加载patch文件
patchManager.loadPatch();
File patchFile = new File(Environment.getExternalStorageDirectory(),"out.apatch");
try {
if(patchFile.exists()){
//指定patch文件的路径
patchManager.addPatch(patchFile.getAbsolutePath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
此时,将带有bug的代码导出一份签名过的apk文件,命名为bug.
然后,我们在代码中修复bug,再重新使用相同的签名导出一份apk文件,命名为fix.
现在,我们将2个apk文件和签名文件一同复制到AndFix-master\tools\apkpatch-1.0.3目录下,使用apkpatch命令产生出patch文件,命令如下:
apkpatch -f fix.apk -t bug.apk -o bug_fix -k test.jks -p 111111 -a test -e
现在将bug.apk文件装到手机上,并将patch文件复制到sd卡指定目录(在真实开发中,此patch文件应该是从服务器下载,并且该patch文件的后缀必须是.apatch);运行带有bug的app,由于代码已经在Application的onCreate中编写了加载了patch文件的代码,所以patch文件将会覆盖掉带有bug的代码。
注意:你可能担心补丁文件放在sd卡上不安全,万一被用户删除了,不就又回到了错误的代码吗?
阿里的AndFix已经考虑了该问题,我们可以尝试删除sd卡的patch文件,你会发现程序的bug仍然被修复了。这是因为AndFix框架在第一次加载补丁文件的时候,将其复制到了/data/data/包名/file目录下,可以去该目录找到patch文件。