最近一年,热修复在Android界很火,相信大家也或多或少的看过某些团队的热修复博文,关于框架选择等等。框架选择很重要,但做好对应的一整套热修复方案,再去变更框架,则来的容易许多。
Andfix
andfix是阿里出的解决线上修复bugs的解决方案,那么今天我们先研究下andfix,以及如何将其运用到项目。
其声称AndFix支持Android 2.3到7.0,不论是ARM或X86架构,同样也支持Dalvik和ART虚拟机,还是32位和64位机型,统统都支持。
andfix的实现原理,如下:
方法替换,Andfix通过自定义的注解来实现方法的替换,因为在ART内部有一个原生方法art_replaceMethod或在Dalvik中有一个dalvik_replaceMethod方法。
如何使用
使用起来很简单:
导入aar包:compile 'com.alipay.euler:andfix:0.5.0@aar'。
在自有application中初始化PatchManager。
加载过往补丁文件。
添加新补丁文件。
dependencies {
compile 'com.alipay.euler:andfix:0.5.0@aar'
}
PatchManager patchManager = new PatchManager(context);
patchManager.init(appversion);//current version
patchManager.loadPatch();
patchManager.addPatch(path);//path of the patch file that was downloaded
原理介绍
apkpatch将两个apk做一次对比,然后找出不同的部分。可以看到生成的apatch了文件,后缀改成zip再解压开,里面有一个dex文件。通过jadx查看一下源码,里面就是被修复的代码所在的类文件,这些更改过的类都加上了一个_CF的后缀,并且变动的方法都被加上了一个叫@MethodReplace的annotation,通过clazz和method指定了需要替换的方法。
然后客户端sdk得到补丁文件后就会根据annotation来寻找需要替换的方法。最后由JNI层完成方法的替换。
如果本地保存了多个补丁,那么AndFix会按照补丁生成的时间顺序加载补丁。具体是根据.apatch文件中的PATCH.MF的字段Created-Time。
补丁方案
andfix上有很多issue,所以如果针对企业,贸然使用该热修复,会导致大量问题。那么针对补丁的一整套方案,才是热修复的关键。例如,如何进行灰度测试,如何控制黑白名单,如何进行补丁版本管理,如何自动化打补丁,如何进行补丁回退。
灰度测试
推进补丁方案,需要进行灰度测试,那么使用白名单机制是必要的。何为灰度测试,即针对某些特定人群,发布特定补丁,进行阶段性测试。该特定人群,可以是公司范围内的职员,可以是公司深度用户等。而如何保证补丁下发特定人群,则需要相关的代码控制。例如在应用开启时,上传该用户的手机相关信息或对应的app版本号,后端通过这些信息判断是否在白名单内,然后检查补丁库中是否有对应补丁。
补丁版本管理
补丁文件跟随app的版本号,所以推荐使用四段式,如3.1.0.1,表明是对应的app版本是3.1.0。相应的,也需要有补丁发布平台,通过该平台上传补丁,前端提交版本信息,后端分析是否有对应补丁。同时也应该注意,增加补丁控制开关,在紧急情况下,可以利用该开关,来阻断补丁的发布。
自动化打补丁
在学习使用andfix中,会使用到apatch工具,而手动打补丁会出现一些问题。相信大部分公司都会利用jenkins构建项目,而对应的签名文件,则放置在服务器。例如当构建一次成功后,会将对应的apk更名,然后发布到公司官网等渠道,保存该apk,若该版本出现问题,修复代码,再次构建,保存该apk,利用该apk和原始的apk进行diff,生成补丁文件,推送至补丁发布平台。这样,一整套流程就清晰了,然后开发人员只需要在预发布环境中,验证补丁是否可正常运行,如能正常运行,就可直接打开补丁发布开关,进行用户推送了。
补丁闪退
当某用户下载完补丁后,由于某些原因,比如国产rom,最新Android版本等,导致其在初始化补丁时,应用就崩溃,也有可能是因为补丁发布失误等情况。针对这些情况,如果没有有效的处理手段,那么就会损失掉这部分用户。如何进行补丁回退,是补丁方案中重要的一环。而解决方案也多种多样,例如,当在执行热修复代码之前,判断补丁崩溃标记是否存在,若不存在,设置一个标记位,然后在执行热修复代码完毕后,再清除该标记,若存在,则跳过热修复代码。
那么如何管理该标记,如果用户在使用某次补丁时,异常崩溃后,如果不对该标记进行管理,即其会导致该用户无法使用补丁文件,解决方案也有很多,例如标记跟随版本号等。
当然针对补丁闪退,还可有其他的回退方案,例如检测到该用户补丁闪退,即进行清除用户补丁文件等必要操作。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。