最近项目需要热修复功能,试了andfix,tinker和hotfix 还是觉得hotfix 比较适合自己的项目。
不废话
正片开始。
1.热修复控制台地址
注册一个账号并登陆开通授权。
进入控制台。
在产品列表中 添加项目
编辑完成后 进入该产品的热修复控制台,并添加应用(Android)
点击创建
事后.jpg
down下来这个叫aliyun-emas-services.json的文件 自己保存 里面有所有key的信息。
其中 红框的这组数据很重要。
基本上前期的准备工作已经完成。
接下来开始创建项目。
在build.gradle中增加 仓库 和引用
repositories { maven { url "http://maven.aliyun.com/nexus/content/repositories/releases" } }
compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.3'
注意该文件中的 versionName 版本号名称 跟后续补丁版本需要匹配。
Androidmanifest.xml 添加权限
添加meta
IDSECRET
APPSECRET
RSASECRET
这三个与上面json文件对应如下:
IDSECRET= hotfix.idSecret
APPSECRET=emas.appSecret
RSASECRET=hotfix.rsaSecret
配置完成 接下来创建application 类
在该类的
attachBaseContext中 初始化热修复的init加载
private void initSophix() {
//获取版本号
String appVersion = "1.0";
try {
appVersion = this.getPackageManager()
.getPackageInfo(this.getPackageName(), 0)
.versionName;
} catch (Exception e) {
}
final SophixManager instance = SophixManager.getInstance();
Log.e("aaaaaa", "版本号= " + appVersion);
instance.setContext(this)
.setAppVersion(appVersion)
.setSecretMetaData(null, null, null) //该类是替换META 标签中的 IDSECRET APPSECRET RSASECRET
.setEnableDebug(true)
.setEnableFullLog()
.setPatchLoadStatusStub(new PatchLoadStatusListener() {
@Override
public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
if (code == PatchStatus.CODE_LOAD_SUCCESS) {
Log.e(TAG, "补丁读取完毕了");
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
Log.e(TAG, "补丁修复完毕了");
//修复完毕后 可以做一些重启 或者提示的动作
}else{
Log.e(TAG, "\n code= " + code);
Log.e(TAG, "mode= " + mode);
Log.e(TAG, "info= " + info);
Log.e(TAG, "handlePatchVersion= " + handlePatchVersion);
}
}
}).initialize();
}
我是在项目启动的时候 检查补丁 然后更新修复 所以我放在里application中的oncreate方法里执行,如果用更新按钮也是可以的。
@Override
public void onCreate() {
super.onCreate();
SophixManager.getInstance().queryAndLoadNewPatch();
}
基本上配置就完成了。
接下来就测试打包数据
旧版本APK 和 修正过的APK 各打包1个(release版本) 。 (随便改个文字什么的就行。 )
下载打包工具:
patch补丁包生成需要使用到打补丁工具SophixPatchTool, 如还未下载打包工具,请前往下载Android打包工具。
Mac版本打包工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatchTool_macos.zip
Windows版本打包工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatchTool_windows.zip
Linux版本打包工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatchTool_linux.zip
调试工具地址:http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/hotfix_debug_tool-release.apk
下载完成后运行 SophixPatchTool.exe
其中选择 旧包和新包
在设置中 设置中设置输出路劲 签名key
其他的看着设置吧 我是默认设置的
.
然后直接点GO
然后得到一个sophix-patch.jar的补丁文件 这个就是修正后的修复文件(不要改名,改名上传不了)。
然后进入阿里开发后台管理平台 在菜单里选择移动热修复 → 补丁管理
先添加版本:
该版本跟自己的build.gradle 中的
versionName 版本号一致。
添加完应用版本后 开始上传补丁(sophix-patch.jar)
确定后在列表中就可以看到上传的补丁了
现在还并没有完成任务,接下来进入详情页
在左下角 点击新建发布
PS : 右侧其实也可以用本地包 测试本地修复 (二维码方式,有兴趣可以试试)
选择全量发布 确定。
当列表发布中后 老的APK应用就可以自动下载补丁更新了。
如果测试中log中 会有部分提示编码,可以对照下表 检查一下自己问题出在哪里 再重新调整即可
//兼容老版本的code说明
int CODE_LOAD_SUCCESS = 1;//加载阶段, 成功
int CODE_ERR_INBLACKLIST = 4;//加载阶段, 失败设备不支持
int CODE_REQ_NOUPDATE = 6;//查询阶段, 没有发布新补丁
int CODE_REQ_NOTNEWEST = 7;//查询阶段, 补丁不是最新的
int CODE_DOWNLOAD_SUCCESS = 9;//查询阶段, 补丁下载成功
int CODE_DOWNLOAD_BROKEN = 10;//查询阶段, 补丁文件损坏下载失败
int CODE_UNZIP_FAIL = 11;//查询阶段, 补丁解密失败
int CODE_LOAD_RELAUNCH = 12;//预加载阶段, 需要重启
int CODE_REQ_APPIDERR = 15;//查询阶段, appid异常
int CODE_REQ_SIGNERR = 16;//查询阶段, 签名异常
int CODE_REQ_UNAVAIABLE = 17;//查询阶段, 系统无效
int CODE_REQ_SYSTEMERR = 22;//查询阶段, 系统异常
int CODE_REQ_CLEARPATCH = 18;//查询阶段, 一键清除补丁
int CODE_PATCH_INVAILD = 20;//加载阶段, 补丁格式非法
//查询阶段的code说明
int CODE_QUERY_UNDEFINED = 31;//未定义异常
int CODE_QUERY_CONNECT = 32;//连接异常
int CODE_QUERY_STREAM = 33;//流异常
int CODE_QUERY_EMPTY = 34;//请求空异常
int CODE_QUERY_BROKEN = 35;//请求完整性校验失败异常
int CODE_QUERY_PARSE = 36;//请求解析异常
int CODE_QUERY_LACK = 37;//请求缺少必要参数异常
//预加载阶段的code说明
int CODE_PRELOAD_SUCCESS = 100;//预加载成功
int CODE_PRELOAD_UNDEFINED = 101;//未定义异常
int CODE_PRELOAD_HANDLE_DEX = 102;//dex加载异常
int CODE_PRELOAD_NOT_ZIP_FORMAT = 103;//基线dex非zip格式异常
int CODE_PRELOAD_REMOVE_BASEDEX = 105;//基线dex处理异常
//加载阶段的code说明 分三部分dex加载, resource加载, lib加载
//dex加载
int CODE_LOAD_UNDEFINED = 71;//未定义异常
int CODE_LOAD_AES_DECRYPT = 72;//aes对称解密异常
int CODE_LOAD_MFITEM = 73;//补丁SOPHIX.MF文件解析异常
int CODE_LOAD_COPY_FILE = 74;//补丁拷贝异常
int CODE_LOAD_SIGNATURE = 75;//补丁签名校验异常
int CODE_LOAD_SOPHIX_VERSION = 76;//补丁和补丁工具版本不一致异常
int CODE_LOAD_NOT_ZIP_FORMAT = 77;//补丁zip解析异常
int CODE_LOAD_DELETE_OPT = 80;//删除无效odex文件异常
int CODE_LOAD_HANDLE_DEX = 81;//加载dex异常
// 反射调用异常
int CODE_LOAD_FIND_CLASS = 82;
int CODE_LOAD_FIND_CONSTRUCTOR = 83;
int CODE_LOAD_FIND_METHOD = 84;
int CODE_LOAD_FIND_FIELD = 85;
int CODE_LOAD_ILLEGAL_ACCESS = 86;
//resource加载
public static final int CODE_LOAD_RES_ADDASSERTPATH = 123;//新增资源补丁包异常
//lib加载
int CODE_LOAD_LIB_UNDEFINED = 131;//未定义异常
int CODE_LOAD_LIB_CPUABIS = 132;//获取primaryCpuAbis异常
int CODE_LOAD_LIB_JSON = 133;//json格式异常
int CODE_LOAD_LIB_LOST = 134;//lib库不完整异常
int CODE_LOAD_LIB_UNZIP = 135;//解压异常
int CODE_LOAD_LIB_INJECT = 136;//注入异常
完事 收工。