Bugly热修复之通过自建服务器管理补丁方案
Bugly虽然提供补丁管理后台,但有时项目可能希望自行管理补丁,今天就简单说一下这个方案。
背景
最近项目想集成Bugly热修复,基本测试已经通了。突然想自行管理补丁,不通过Bugly管理平台下发。于是就抽空看了一下Bugly 资料和Tinker部分源码,初步确定了一下方案步骤,在此进行一下记录。
步骤流程
主要步骤流程如下图所示:
其中版本标志可以自行定义,只要能区分出不同的版本,保证唯一性即可。最简单的就比如 VersionName ,VersionCode,PackageName组合等,也可以考虑上传DEVICEID用来精确定位。
- 移动端打出的补丁包交由后台进行上传管理。移动端每次启动的时候进行主动进行补丁检测,也可以通过后台push进行检测。
- 后台根据移动端传递的版本标志,进行检测有无此版本对应的补丁。后台接口返回的字段包含needFix,needRollback, RollbackStrategy,apkURL ,apkMD5, apkSize以及其他一些信息字段。
- 如果没有补丁,正常启动。如果有补丁信息,根据needRollback判断是否需要回滚补丁。
- 如果需要回滚,根据RollbackStrategy回滚策略进行回滚。如果不需要回滚, 判断是否需要更新,检测的方式这里是通过本地记录的补丁MD5值与接口返回的apkMD5进行比对。
- 如果 MD5一致,说明当前已经打了这个补丁,不需要重复下载。如果不一致,下载补丁到指定目录,然后进行补丁合并,补丁成功后会删除指定目录下的补丁文件,成功后本地记录更新补丁MD5值。
- 等待下次重启修复。
注意: Tinker 源码中就是采用的记录补丁MD5值信息作为标记的,我们可以采用Tinker中的已有的API即可。具体请阅读以下源码:
@Override
public boolean tryPatch(Context context, String tempPatchPath, PatchResult patchResult) {
//省略部分代码
......
String patchMd5 = SharePatchFileUtil.getMD5(patchFile);
if (patchMd5 == null) {
ShareTinkerLog.e(TAG, "UpgradePatch tryPatch:patch md5 is null, just return");
return false;
}
//use md5 as version
patchResult.patchVersion = patchMd5;
ShareTinkerLog.i(TAG, "UpgradePatch tryPatch:patchMd5:%s", patchMd5);
//check ok, we can real recover a new patch
final String patchDirectory = manager.getPatchDirectory().getAbsolutePath();
File patchInfoLockFile = SharePatchFileUtil.getPatchInfoLockFile(patchDirectory);
File patchInfoFile = SharePatchFileUtil.getPatchInfoFile(patchDirectory);
final Map<String, String> pkgProps = signatureCheck.getPackagePropertiesIfPresent();
if (pkgProps == null) {
ShareTinkerLog.e(TAG, "UpgradePatch packageProperties is null, do we process a valid patch apk ?");
return false;