博客转移到个人站点:http://www.wangchengmeng.club/2018/02/04/Android%E7%83%AD%E4%BF%AE%E5%A4%8DAndFix/
欢迎来吐槽
我相信很多人都遇到过或者担心已经上线的项目,突然发现一些比较致命的bug,首先想到的就是重新发一个版本去覆盖线上的版本,但有时候这样的成本比较大,而且用户体验极其不好,而且有时候会遇到一些bug不值得去重新发布新的版本情况。所以就提出了热修复的概念,目前 已经有一些比较成熟的这方面的框架:
hotfix:https://github.com/dodola/HotFix
Nuwa:https://github.com/jasonross/Nuwa
DroidFix:https://github.com/bunnyblue/DroidFix
AndFix:https://github.com/alibaba/AndFix
关于这些框架原理其实大概差不多,可以参考:
安卓App热补丁动态修复技术介绍:
https://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=400118620&idx=1&sn=b4fdd5055731290eef12ad0d17f39d4a&scene=1&srcid=1106Imu9ZgwybID13e7y2nEi#wechat_redirect
Android dex分包方案:http://my.oschina.net/853294317/blog/308583
大概的原理都是结合这两者去实现的,具体原理课参考:
博客:http://blog.csdn.net/lmj623565791/article/details/49883661/
在这里我就将自己用到的AndFix讲解一下吧,希望有已经熟练运用过Andfix的,或者过程中遇到问题的,再或者用过其他的能够一起分享一下,互相学习。
AndFix的github地址
https://github.com/alibaba/AndFix
添加依赖
dependencies {
compile ‘com.alipay.euler:andfix:0.4.0@aar’
}
在提高用户体验,不知不觉中修复线上bug,在Application的onCreate方法中,程序启动的时候,就加载补丁进行热修复:
1、初始化
patchManager = new PatchManager(context);
patchManager.init(appversion);//current version
2、load patch
patchManager.loadPatch();
3、加载补丁进行修复
(1)、下载补丁
为了防止下载过程中丢包的问题,最好服务端返回下载补丁文件的MD5值,客户端下载完毕后,比较本地补丁包和服务端补丁包的MD5值,如果相同,那就直接patchManager.addPatch(path),如果不同,说明下载过程中出现了丢包现象,此时是不能直接打补丁(打上去也许会导致客户端crash),把本地文件删除再重新下载。
(2)、加载补丁
atchManager.addPatch(path);//path of the patch file that was downloaded
注意:
该path是你存放apatch文件的地方,如果你存放在SDCard中,请添加读写SDCard权限,在6.0要注意读写SDCard的权限属于运行时权限要动态申请。
4、打补丁包
打好补丁包需要用到apkpatch点击下载工具
(1)、然后打开命令窗口进入到apkpatch文件夹下
(2)、使用命令生成补丁
usage: apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
-a,--alias <alias> keystore entry alias.
-e,--epassword <***> keystore entry password.
-f,--from <loc> new Apk file path.
-k,--keystore <loc> keystore path.
-n,--name <name> patch name.
-o,--out <dir> output dir.
-p,--kpassword <***> keystore password.
-t,--to <loc> old Apk file path.
(3)、生成了多个补丁,将补丁合并:
usage: apkpatch -m <apatch_path...> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
-a,--alias <alias> keystore entry alias.
-e,--epassword <***> keystore entry password.
-k,--keystore <loc> keystore path.
-m,--merge <loc...> path of .apatch files.
-n,--name <name> patch name.
-o,--out <dir> output dir.
-p,--kpassword <***> keystore password.
5、混淆
-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
native ;
}
做完了上面步骤,在项目中我们需要去请求接口,如果后台有上传补丁,我们需要下载下来,再加载补丁修复bug。
目前是这样处理的,不知道还有没有更好的办法,似乎有些手机不支持,目前还没有测试到具体那些手机不支持,希望交流。