引言
一直觉得android维护成本挺高的,如果版本出现bug,需要马上发布新版,然后去应用市场申请。这个时候可能需要很长的一段时间,造成用户的流失。
这个时候如果可以不知不觉的修复一些bug就好了。只有你想不到,没有人做不到。Sophix诞生了。记得以前关于热修复生成补丁需要进行繁琐的操作。而Sophix的图形界面化简单操作就可以生成补丁。
Sophix优秀的地方在于它可以对部分修改进行热启动,也就是不说,不需要重启app部分bug就能通过补丁直接修复!(这里需要研究一下什么时候会热启动,什么时候会冷启动)
阿里云申请
1.首先去阿里云申请一个账号,进行实名认证后就可以对产品进行申请了。
阿里云首页链接:https://www.aliyun.com/?utm_content=se_1000301881
问题记录:实名认证时,手机支付宝无法识别二维码(火狐浏览器),后换成谷歌浏览器可扫描。
2.在搜索框搜索“热修复”,点击“管理控制台”新建项目即可。
注意:项目文件大小写需和应用项目保持一致。
3.查看并保存好,与AndroidManifest.xml文件中meta-data对应
"emas.appSecret":"",
"hotfix.idSecret":"",
"hotfix.rsaSecret":"",
项目配置
1.在应用项目文件下的build.gradle文件下加入
allprojects {
repositories {
google()
jcenter()
maven{
// hot fix 依赖库
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
}l
2.app下的build.gradle下加入热修复依赖
implementation 'com.aliyun.ams:alicloud-android-hotfix:3.2.6'
3.在AndroidManifest.xml中配置好key
<!-- 热修复配置 -->
<meta-data
android:name="com.taobao.android.hotfix.IDSECRET"
android:value="你的 id secret"/>
<meta-data
android:name="com.taobao.android.hotfix.APPSECRET"
android:value="你的 app secret"/>
<meta-data
android:name="com.taobao.android.hotfix.RSASECRET"
android:value="你的 RSA secret"/>
4.记得要加入网络的权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--危险权限 外部存储读权限 调试工具使用时需要添加 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
5.最好是新建一个关于热修复的类如:
这么做可以非常友好的与应用其他代码分离开来。
public class SophixStubApplication extends SophixApplication {
private final String TAG = "SophixStubApplication";
// 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
@Keep
@SophixEntry(HotFixApplication.class)
static class RealApplicationStub {
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 如果需要使用MultiDex,需要在此处调用。
// MultiDex.install(this);
initSophix();
}
private void initSophix() {
String appVersion = "1.1"; //此处应该是你的app versionName版本
try {
appVersion = this.getPackageManager()
.getPackageInfo(this.getPackageName(), 0)
.versionName;
} catch (Exception e) {
}
final SophixManager instance = SophixManager.getInstance();
instance.setContext(this)
.setAppVersion(appVersion)
.setSecretMetaData(null, null, null)
.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.i(TAG, "sophix load patch success!");
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
// 如果需要在后台重启,建议此处用SharePreference保存状态。
Log.i(TAG, "sophix preload patch success. restart app to make effect.");
}
}
}).initialize();
}
}
注意:
1. appVersion应与应用版本versionName保持一致
2. @SophixEntry(HotFixApplication.class):HotFixApplication应该是你的app的Application。
3. RealApplicationStub 我还不知道是什么
6.在AndroidManifest.xml中
<application
android:name=".SophixStubApplication"
··· />
7.在应用的Application下的onCreate方法中调用
SophixManager.getInstance().queryAndLoadNewPatch();
8.如果代码加了混淆,需要在混淆文件中加入:
-keepclassmembers class com.excellence.hotfix.HotFixApplication {
public <init>();
}
-keep class com.excellence.hotfix.SophixStubApplication$RealApplicationStub
注意:HotFixApplication 为应用的Application。
生成补丁
1.在阿里云下载生成补丁工具:
可进入阿里云下载:https://help.aliyun.com/document_detail/93826.html?spm=a2c4g.11186623.2.10.44005b84iYQlfw
也可以直接用下方链接下载。
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
windows下为解压补丁工具后,打开\SophixPatchTool\SophixPatchTool.exe。
其他系统生成补丁方式可见阿里云文档:https://help.aliyun.com/document_detail/93826.html?spm=a2c4g.11186623.2.10.44005b84iYQlfw
如图:
发布补丁
1.新建版本
版本应与app的版本一致,此处版本为1.1。
2.上传补丁
将生成补丁上传至阿里云,并对补丁进行发布。
其他
1.注意应项目大小写保持一致。
2.官方文档是最好的老师。
3.错误码
//兼容老版本的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;//注入异常