1 集成
1.1 注册账号
去阿里云注册开发则帐号,注册成功后进入控制台,添加移动热修复服务,如图
如果刚注册,必须进行实名认证,才能使用。
认证完毕,再次进入控制台,添加移动热修复服务
1.2 集成准备
1.2.1 android studio集成方式
gradle远程仓库依赖, 打开项目找到app的build.gradle文件,添加如下配置:
添加maven仓库地址:
buildscript {
...
repositories {
...
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
...
}
注意:Android Studio 3.0 的配置还要再加上这句:
allprojects {
repositories {
...
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
}
否则报错:
1.2.2 权限说明
1.2.3 配置AndroidManifest文件
在AndroidManifest.xml中间的application节点下添加如下配置:
RSA密钥位置
1.2.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
1.2.6 代码接入
// initialize的调用应该尽可能的早,必须在Application.attachBaseContext()的最开始,不建议在Application.onCreate()中初始化。
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
initHotfix();
Log.e("Sophix", "调用了");
}
private void initHotfix() {
String appVersion;
try {
appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
} catch (Exception e) {
appVersion = "1.0";
}
SophixManager.getInstance().setContext(this)
.setAppVersion(appVersion)
.setAesKey(null)
// .setAesKey("******")
.setEnableDebug(true)
.setSecretMetaData(appId, appSecret, rsaSecret)
.setPatchLoadStatusStub(new PatchLoadStatusListener() {
@Override
public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
String msg = new StringBuilder("").append("Mode:").append(mode)
.append(" Code:").append(code)
.append(" Info:").append(info)
.append(" HandlePatchVersion:").append(handlePatchVersion).toString();
if (msgDisplayListener != null) {
msgDisplayListener.handle(msg);
} else {
cacheMsg.append("\n").append(msg);
}
}
}).initialize();
}
1.2.7 调用queryAndLoadNewPatch方法
// queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,
// 如onCreate中,或者其他地方(最好就在Application中,如果在Activity中调用,可能由于多次创建,导致调用次数增多,增加费用)
SophixManager.getInstance().queryAndLoadNewPatch();
你可能会有这样的疑问,平台是什么时候开始侦测到正在运行的设备的?
就是在queryAndLoadNewPatch方法被调用之后
2 使用
2.1 生成补丁
2.1.1 下载打包工具
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
2.1.2 生成补丁包
安装下载的打包工具,(Mac 必须将 打包工具 移到 应用程序 中,否则会导致打包工具闪退)
然后配置签名信息,指定补丁包的输出路径(只第一次需要配置这些信息)
直接选择旧包和新包(旧包指有bug的包,新包是修复完bug的包)
然后点击 GO!
补丁包就会生成在你指定的输出路径下
注意,补丁包的名字必须是 sophix-patch.jar ,不能修改!
然后进入控制台,添加版本,上传补丁
注意,版本号必须和项目保持一致
// 默认版本号是 1.0,会获取当前版本
String appVersion;
try {
appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
} catch (Exception e) {
appVersion = "1.0";
}
SophixManager.getInstance().setContext(this)
.setAppVersion(appVersion)
项目中的版本号( build.gradle 中的 versionName )
defaultConfig {
applicationId "com.risecenter.rise_online_android"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
依次进行下列步骤即可
灰度发布:可指定修复补丁的手机数量
全量发布:用于生产环境。经本地测试,灰度发布测试没问题后,就可以全量发布了
发布完毕,杀掉进程(而不是返回)才会生效。
3 相关链接
官方文档
快速接入
生成补丁
上传及发布补丁
常见问题
Hotfix补丁不生效排查步骤
Hotfix补丁工具报错排查步骤
4 不支持四大组件的添加(不直接支持)
好吧,我知道,但我还是尝试了一下,报错如下:
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.risecenter.rise_online_android/com.risecenter.rise_online_android.ui.activity.Main2Activity}; have you declared this activity in your AndroidManifest.xml?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1932)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1615)
at android.app.Activity.startActivityForResult(Activity.java:4472)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67)
at android.app.Activity.startActivityForResult(Activity.java:4430)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:720)
at android.app.Activity.startActivity(Activity.java:4791)
at android.app.Activity.startActivity(Activity.java:4759)
at com.risecenter.rise_online_android.ui.activity.MainActivity$onCreate$1.onClick(MainActivity.kt:21)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
上面报错我们并不陌生,意思是Main2Activity没有在 AndroidManifest.xml 中注册。
// 事实上我已经注册了,但是打补丁后还是报错
为了验证不是代码问题,我直接打了一个新包在真机上,是可以跳转到Main2Activity的。