一.内部版本接入
内部最新版本为0.7.48,接入方式与外部版本相同,不再赘述。
详情看:ROBUST接入
着重讲解外部版本与内部版本的区别:
外部版本需要设定补丁加载路径以及加载时机,内部则配合Env自行保存及加载。
内部使用需要在Application中手动初始化Robust,如图:
根据观察的补丁加载时机以及抓包的结果来看。
推测:内部补丁加载时机为Application初始化,会去根据上述参数构建一个get请求,请求补丁列表。如果有补丁,则下载补丁然后自动加载。所以补丁加载只会在
App进程被杀之后才生效。
这里说句题外话。内部使用与外部使用最大的区别在于,我团内部使用,是有Env发版策略配套,补丁放置的服务器由专门的人员去维护。而外部人员使用,需要自己选择补丁放置的服务器路径,自己
去订制补丁请求的策略。在代码上的区别就在于 PatchManipulate 这个类中的更改:
外部版本需要继承上述类,而内部版本已经替我们写好了子类。
是不是很眼熟?在初始化Robust时会传入上述参数,最终依据这些数据,组成一个get请求,请求相应的补丁。
下面是一个完整请求的例子:
URL
http://10.4.239.113:9000/appupdate/patch/list?apiLevel=22&dev=M1-NL&devModel=M1-NL&brand=SUNMI&jvmVersion=2.1.0&userId=27997173&channel=jenkins&cpuArc=armeabi-v7a&robustVersion=60000&apkHash=1b8581e3eb0c615af855a8086a281e56&applicationId=com.sankuai.erp.waiter&uuid=43e0b9dc7902464a8a34418f9a913a160000000000000271990&appVersion=2.1.0
当发现请求能拿到补丁时,会请求到下载地址:
根据下载地址,下载补丁,然后放置在指定的文件地址中。
Tips:内部使用时,注意Robust.xml中的 patchPackname 路径设置为 com.meituan.robust.patch
二.补丁制作及发布
发版原则:
第零、首先确保自己的修改能解决问题,而不是自己对修改没有信心,抱着试试的心态。简单的验证方式就是把自己的修改提交到git,然后使用jekins打一个release包,验证问题是否修复
第一、不推荐滥用热补丁,对于比较大的问题才予以修复(线上修复的范围:线上bug P1 P2予以修复、p3待定(业务老大和QA商量,通知平台QA wangkai17参与),其余不予以上线),热补丁上线是存在风险的,可能存在着QA没有测试到的场景,产生一些意想不到的bug。
补丁上线之前需要邮件周知自己业务老大和QA老大,[email protected],[email protected],[email protected],[email protected],[email protected],邮件主题:xx业务+版本号+修复文件简要说明,例如:团购业务6.7.1版本修复旅游频道支付bug,邮件内容中指明具体修复的bug以及技术评估范围和测试范围.
业务老大和QA老大同意之后才允许上线,上线之后出现的问题,需要由上线补丁的操作者、QA以及相关人员共同负责(eva后台有记录),所以慎重上线。
第二、如果责任人都不确定是否能修复bug,或者说bug不是必现的,责任人自己也没有把握修复问题,那就不要上了。以测试的心态去线上操作热补丁,我们是拒绝的。
第三、晚上七点之后拒绝上线热补丁,热补丁制作出来需要进过QA的测试,不可以匆匆忙忙的测试,甚至在没有QA的参与下测试,然后直接上线,需要给予QA足够的时间来测试。
第四、补丁上线之后,需要留意crash数据(一般留意一个星期的数据,crash工作台,搜索crash关键数据:robust或者patch),发现数据异常,需要立即定位问题,及时下线补丁。
补丁制作:
1.手动制作补丁
补丁制作基于线上版本的最后一次commit,保证代码一致后,执行线上打包命令,保存生成的两个文件。
这里以服务员App举例:
手动打线上包命令:./gradlew assembleRelease signRelease
打包完成之后,保留mapping,methodsMap.robust文件。
在主工程src同级目录下建立robust文件,将上述保留文件copy进去。
然后,更改我们需要修复的方法。
更改规则如下:
在改动的方法上面添加@Modify注解或者在修改的方法里面调用RobustModify.modify()(针对Lambda表达式)
@Modifyprotectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
//或者是被修改的方法里面调用RobustModify.modify()方法protectedvoid onCreate(Bundle savedInstanceState) {
RobustModify.modify()
super.onCreate(savedInstanceState);
}
新增的方法和字段使用@Add注解
//增加方法@AddpublicString getString() {
return”Robust”;
}
//增加类@AddpublicclassNewAddCLass {
publicstaticStringget() {
return”robust”;
}
}
代码修改完毕,主工程build.gradle中打开插件制作。
//制作补丁时将这个打开,auto-patch-plugin紧跟着com.android.application
//apply plugin: ‘auto-patch-plugin’
接着再运行一次刚才的打包命令,补丁制作好后会抛出一个RuntimeException,代表补丁就已经做好啦。
2.补丁自动制作
此处已有详细文档,不再赘述
https://wiki.sankuai.com/pages/viewpage.action?pageId=727552545
补丁制作详细版
三.补丁发布
经过前面几步,终于辛辛苦苦制作出补丁,现在终于可以把补丁放到服务器上测试了。热补丁的服务器在eva上(因此发布补丁的权限和eva服务器的权限是一样的,eva权限申请流程),eva有测试服务器和正式服务器:
其中测试服务器上传补丁页面的地址为:http://10.4.239.113:8001/Android/waimai/addpatch(以外卖为例,域名中是包含appname 的) 补丁的管理页面为:http://10.4.239.113:8001/Android/waimai/patches
正式服务器上传补丁页面的地址为:http://appupdate.sankuai.com/Android/waimai/addpatch 补丁的管理页面为:http://appupdate.sankuai.com/Android/waimai/patches
以测试服务器为例:
服务员测试服补丁发布地址
点击补丁管理,会出现一个添加补丁的地址
然后如何确定补丁是否下发成功了?
三.补丁的测试
建议测试的时候在测试服务上面测试,免得污染线上的环境。为了把线上apk中的获取补丁的请求转发到测试服务器上,需要使用Charles进行转发,需要导入配置文件,
![这里写图片描述](https://123.sankuai.com/km/api/file/16297341/16310412)
测试的时候抓取手机log,如果补丁没有导致apk崩溃并且修复了bug,那么就去log中搜索exception,看看有没有补丁引起的其他异常,如果异常的堆栈中含有patch或者robust就表示和补丁有关系。
又或者不加载补丁的时候没有exception,加载补丁之后却出现了exception,那么也是和补丁相关的异常
判断补丁是否下载:
尽可能的覆盖所有使用到被补丁方法的场景
四.补丁的正式上线
补丁经过QA的测试之后,QA和bug影响业务的老大同意之后上线,各个独立app各自负责补丁上线