什么是热修复?就是指能够修复软件漏洞的一些代码,是一种快速、低成本修复产品软件版本缺陷的方式(百度)。也就是当产品上线遇到bug,这个时候我们去发布一个新的版本,不但要过市场审核,而且发布没有多久又更新,用户体验也不好。这个时候我们就要考虑到使用热修复了,在app启动的时候会去联网下载差分包然后进行修复。
本文主要是介绍阿里的热修复Sophix的基本使用流程。Sophix提供了一套更加完美的客户端服务端一体的热更新方案,做到了图形界面一键打包、加密传输、签名校验和服务端控制发布与灰度功能,让你用最少的时间实现最强大可靠的全方位热更新。
创建应用
创建应用主要是到阿里平台去创建,步骤如下:
首先进入MHub控制台
之后进入移动热修复控制台
上图中AppId、AppSecret以及RSA密钥 后面集成到项目会用到
集成到Android项目
集成准备
1.配置build.gradle(Project:项目名)文件,添加如下配置:
repositories {
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
下面是我的build.gradle文件内容:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
2.配置build.gradle(Module:app)文件,添加如下配置:
compile 'com.aliyun.ams:alicloud-android-hotfix:3.0.3'
传递性依赖utdid这个sdk, 所以不需要重复依赖utdid.但是另一方面其它阿里系SDK也可能依赖了utdid这个SDK, 如果编译期间报utdid重复, 所以此时进行如下处理即可, 关闭传递性依赖:
compile ('com.aliyun.ams:alicloud-android-hotfix:3.0.3') {
exclude(module:'alicloud-android-utdid')
}
utdid实际上是为设备生成唯一deviceid的一个基础类库
如若仓库访问失败, 那么用本地依赖的方式进行依赖,SDK下载
3.Sophix使用到以下权限
<! -- 网络权限 -->
<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"/>
READ_EXTERNAL_STORAGE/ACCESS_WIFI_STATE权限属于Dangerous Permissions,自行做好android6.0以上的运行时权限获取
4.配置AndroidManifest文件
在AndroidManifest.xml中间的application节点下添加如下配置:
<meta-data
android:name="com.taobao.android.hotfix.IDSECRET"
android:value="App ID" />
<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密钥" />
将上述value中的值分别改为通过平台HotFix服务申请得到的App ID、App Secret和RSA密钥。具体可查看创建应用步骤
5.混淆配置
#基线包使用,生成mapping.txt
-printmapping mapping.txt
#生成的mapping.txt在app/buidl/outputs/mapping/release路径下,移动到/app路径下
#修复后的项目使用,保证混淆结果一致
#-applymapping mapping.txt
#hotfix
-keep class com.taobao.sophix.**{*;}
-keep class com.ta.utdid2.device.**{*;}
#防止inline
-dontoptimize
开始使用
在项目的Application中配置如下:
@Override
public void onCreate() {
super.onCreate();
init();
}
private void init() {
// initialize最好放在attachBaseContext最前面
SophixManager.getInstance().setContext(this)
.setAppVersion(BuildConfig.VERSION_NAME)
.setAesKey(null)
.setEnableDebug(true)
.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,"表明补丁加载成功");
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
// 表明新补丁生效需要重启. 开发者可提示用户或者强制重启;
// 建议: 用户可以监听进入后台事件, 然后应用自杀
Log.i(TAG,"表明新补丁生效需要重启. 开发者可提示用户或者强制重启");
} else if (code == PatchStatus.CODE_LOAD_FAIL) {
// 内部引擎异常, 推荐此时清空本地补丁, 防止失败补丁重复加载
// SophixManager.getInstance().cleanPatches();
Log.i(TAG,"内部引擎异常, 推荐此时清空本地补丁, 防止失败补丁重复加载");
} else {
// 其它错误信息, 查看PatchStatus类说明
Log.i(TAG,"其它错误信息, 查看PatchStatus类说明");
}
}
}).initialize();
// queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
SophixManager.getInstance().queryAndLoadNewPatch();
}
initialize的调用应该尽可能的早,必须在Application.attachBaseContext()或者Application.onCreate()的最开始进行SDK初始化操作,否则极有可能导致崩溃。而查询服务器是否有可用补丁的操作可以在后面的任意地方。
生成补丁包
patch补丁包生成需要使用到打补丁包工具SophixPatchTool
Mac版下载
Windows版下载
生成补丁包工具:
主窗口
-
旧包:<必填> 选择基线包路径(有问题的APK)。
-
新包:<必填> 选择新包路径(修复过该问题APK)。
-
日志:打开日志输出窗口。
-
高级:展开高级选项,见下。
-
设置:配置其他信息,见下。
-
GO!:开始生成补丁。
高级选项窗口
-
强制冷启动:勾选的话强制生成补丁包为需要冷启动才能修复的格式。默认不选的话,工具会根据代码变更情况自动选择即时热替换或者冷启动修复。
-
不比较资源:打补丁时不比较资源的变化。
-
不比较SO库:打补丁时不比较SO库的变化
设置选项窗口
-
补丁输出路径:<必填> 指定生成补丁之后补丁的存放位置,必须是已存在的目录。
-
Key Store Path:<选填>本地的签名文件的路径,不输入则不做签名。
-
Key Store Password:<选填>证书文件的密码。
-
Key Alias:<选填>Key的别名。
-
Key Passwrod:<选填>Key的密码。
-
AES Key:<选填>自定义aes秘钥, 必须是16位数字或字母的组合。必须与setAesKey中设置的秘钥一致。
-
Filter Class File:<选填>本地的白名单类列表文件的路径,放进去的类不会再计算patch,文件格式: 一行一个类名。
注意事项
-
支持多渠道包仅选用某个渠道包的补丁,只需要保证变化相同即可,不过对于不同的基线包最好进行全面的测试。
-
发布前请严格按照:扫码内测 => 灰度发布 => 全量发布的流程进行,以保证补丁包能够正常在所有Android版本的机型上生效。
-
mac下的补丁工具若出现一打开就崩溃的情况,请将补丁工具移到“应用程序”目录下即可。
上传补丁包到后台
上传补丁包需要借助于阿里云移动开发平台,登录平台后,首次上传需要创建版本后再上传与之对应版本的补丁包文件,步骤如图:
注:
补丁文件名称规范:
Android:文件名必须为:sophix-patch.jar;
调试工具
调试工具下载
调试工具用于patch正式发布前的调试环节
-
扫码二维码方式,将刚刚上传到后台的补丁通过扫描二维码下载到本地,尝试加载补丁;
-
应用本地补丁方式,传入本地补丁的绝对路径,尝试加载补丁。
二维码获取方式如下:
补丁包加载成功后,打开或重新启动(防止没有及时生效的情况)应用进行查看。
也可查看我博客的另一个地址:https://dev.19ba.cn/android/125.html