一、概述
随着技术的高速发展与创新,热修复如雨后春笋般涌现,如美团的Robust、饿了么的Amigo、微信的Tinker以及阿里的Andfix和Sophix。站在巨人的肩膀上,可以让我们视野更加开阔,现在就跟随我一起集成阿里的Sophix吧! 滴滴滴,开车啦……
二、热修复方案对比
可以看出阿里的这款热修复产品不仅支持的替换类型全面,而且接入灰常easy,小伙伴们有木有很激动啊,之前集成过微信的Tinker,确实比Sophix稍微复杂一点!
三、准备工作
创建阿里账号,选择移动热修复,创建产品,创建应用,这样一套技能就可以mscp啦,最后是这样的:
提醒一下,集成这个产品需要实名认证的,所以我用的支付宝登录!!!
四、集成步骤
接下来是放大招开启carry模式的时刻啦……
1、在project的gradle中添加maven仓库:
buildscript {
repositories {
jcenter()
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
google()
}
}
2、app的gradle添加阿里的远程依赖:
implementation 'com.aliyun.ams:alicloud-android-hotfix:3.1.8'
3、manifest配置相关信息:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<!--热修復meta-data-->
<meta-data
android:name="com.taobao.android.hotfix.IDSECRET"
android:value="IDSECRET"/>
<meta-data
android:name="com.taobao.android.hotfix.APPSECRET"
android:value="APPSECRET"/>
<meta-data
android:name="com.taobao.android.hotfix.RSASECRET"
android:value="RSASECRET"/>
<!--热修復meta-data-->
3、代码中需要添加的类:
新建一个SophixStubApplication类继承SophixApplication ,并在manifest指定SophixStubApplication类:
/**
* Created by lin on 2017/12/19.
*/
public class SophixStubApplication extends SophixApplication {
private final String TAG = "SophixStubApplication";
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 如果需要使用MultiDex,需要在此处调用。
// MultiDex.install(this);
initSophix();
}
@Override
public void onCreate() {
super.onCreate();
// queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
/** 补丁在后台发布之后, 并不会主动下行推送到客户端, 客户端通过调用queryAndLoadNewPatch方法查询后台补丁是否可用*/
SophixManager.getInstance().queryAndLoadNewPatch();
}
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("lin", "appVersion= " + appVersion);
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.e(TAG, "sophix load patch success!");
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
// 如果需要在后台重启,建议此处用SharePreference保存状态。
Log.e(TAG, "sophix preload patch success. restart app to make effect.");
}else{
Log.e("lin", "code= " + code);
Log.e("lin", "mode= " + mode);
Log.e("lin", "info= " + info);
Log.e("lin", "handlePatchVersion= " + handlePatchVersion);
}
}
}).initialize();
}
// 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
@Keep
@SophixEntry(MyRealApplication.class)
static class RealApplicationStub {
}
}
新建一个MyRealApplication类继承Application:
/**
* Created by lin on 2017/12/19.
*/
public class MyRealApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Log.e("lin", "MyRealApplication start" );
}
}
稍微看一下PatchStatus 类:
public class PatchStatus {
public static final int CODE_LOAD_SUCCESS = 1;
public static final int CODE_ERR_INBLACKLIST = 4;
public static final int CODE_REQ_NOUPDATE = 6;
public static final int CODE_REQ_NOTNEWEST = 7;
public static final int CODE_DOWNLOAD_SUCCESS = 9;//差异包加载成功
public static final int CODE_DOWNLOAD_BROKEN = 10;
public static final int CODE_UNZIP_FAIL = 11;
public static final int CODE_LOAD_RELAUNCH = 12;//差异包加载成功,重启生效
public static final int CODE_REQ_APPIDERR = 15;
public static final int CODE_REQ_SIGNERR = 16;
public static final int CODE_REQ_UNAVAIABLE = 17;
public static final int CODE_REQ_SYSTEMERR = 22;
public static final int CODE_REQ_CLEARPATCH = 18;//停止推送
public static final int CODE_PATCH_INVAILD = 20;
......
}
4、添加混淆:
#sophix
#基线包使用,生成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.**{*;}
-keepclassmembers class com.lin.opensourcelist.SophixStubApplication{
public <init>();
}
# 如果不使用android.support.annotation.Keep则需加上此行
# -keep class com.my.pkg.SophixStubApplication$RealApplicationStub
好了,通过以下步骤,基本的功能已经初始化ok啦,现在来验证一下是否可行……
五、验证
1、添加版本号(与gradle中的需要一致):
2、生成补丁包:
下载打包工具
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
直接把有问题的安装包与修复后的安装包选择上,其他都不用设置,然后点击GO!就生成了差异jar包:
3、发布补丁包:
点击上传补丁:
点击查看详情:
现在就可以通过测试工具验证是否补丁包发送成功
首先连接你的应用:
然后扫描二维码:
出现以上信息说明差异包加载成功,这样给的提示是需要重启应用才生效:
修复之前的界面:
重启之后的界面:
验证成功就可以发布了,这里可以采用全量发布和灰度发布,我直接选择全量发布,然后在模拟器看看是否成功:
状态已变成已发布了。
看看打印的log,可以看出差异包已经下载好了,重启一下就可以生效了:
这是重启后的日志,可以看出没有更新内容了,说明已是最新的补丁包:
去控制台看看有没有推送数据:
果然有推送数据(模拟器测试的一台)……
六、总结
最后这个热修复产品推送数量也是有限制的,具体多少点这里查看,给大家推荐阿里的热修复书籍,学习一下它背后的技术原理,滴滴,车已到站,请陆续下车……