赞
踩
第一章、准备工作
1、申请阿里云账号;
2、开通阿里云移动管理服务;
3、开通阿里云移动服务平台EMAS.
4、创建一个新产品,即需要接入的APP产品。
第二章:接入热修复SDK
您可以在应用管理页面获取配置SDK所需要的基本信息。包括:
Demo程序下载地址:
https://github.com/aliyun/alicloud-android-demo
安卓Demon:
https://github.com/joedan0104/SophixDemo
1、添加热修复依赖库
在项目的app的build.gradle中添加Maven仓库
- repositories {
- maven {
- url "http://maven.aliyun.com/nexus/content/repositories/releases"
- }
- }
在dependencies增加热修复库坐标版本依赖
compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.8'
2、AndroidManifest增加需要的权限
包括读写SD卡、网络权限。
- <! -- 网络权限 -->
- <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"/>
3、配置APP热修复相关数据
在AndroidManifest的application节点下,配置热修复字段。
- <!-- 热修复字段 -->
- <meta-data
- android:name="com.taobao.android.hotfix.IDSECRET"
- android:value="${HOTFIX_APPID}" />
- <meta-data
- android:name="com.taobao.android.hotfix.APPSECRET"
- android:value="${HOTFIX_APPSECRET}" />
- <meta-data
- android:name="com.taobao.android.hotfix.RSASECRET"
- android:value="${HOTFIX_RSA}" />
这些字段在编译的时候写入具体的值。
这几个值的阿里云控制台用户创建的APP对应的热修复的值。
其中APPID:对应的AppKey
APPSECRET:对应的AppSecret
RSA:对应的Rsa
- def config = rootProject.ext// android基本配置
- android {
- compileSdkVersion config.android.compileSdkVersion
- buildToolsVersion config.android.buildToolsVersion
- defaultConfig {
- applicationId "com.cdel.sophixdemo"
- minSdkVersion config.android.minSdkVersion
- targetSdkVersion config.android.targetSdkVersion
- versionCode 1
- versionName "1.0.1"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- // dex突破65535的限制
- multiDexEnabled true
- //个别机器添加热修复导致Vitamio 崩溃问题
- ndk {
- abiFilters "armeabi", "armeabi-v7a"
- }
- // AndroidManifest替换参数
- manifestPlaceholders = [
- HOTFIX_APPID : "25994860",
- HOTFIX_APPSECRET : "f63fcee692a46eb81da4c7a10fe1cd4f",
- HOTFIX_RSA : "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCiD+oeBqhp79WsNwHUjzUy6ljWM6LgATtXoSFm0KErs8DeF3BUPx9P0fSF8grXh7/OoLlAk5uLC11v51mSbKP9OhQ67doHFBhJT8Og5ixIaUT9vV05KksxM85cXV/Ze7o9rjzLtHKbg4ySe/LjiQNdp7SLAhauUXHrEMJpGJaORFVQVtqCrkMjgsvx1ZPmhI8mg6U6VOYcVD2rkLV1jyQcSvcJXtJtERtRBLK2R3IRiC2Oy/IosYJjGeOrN/KMWbMQOC36p7rMOj+xYeOiDyxHX9v+5TRUZ/NXjku57CmjIVcBfF7goBvtay1TIsp1ggDp51Wsg/fGB5KIT6ZPdhzhAgMBAAECggEAYVc1w/szxQ2tRdd0Xfv2dDKWUXKKbgnPXv8FVQATDnDVc5CYg8G2SPdO6/VJ1dNPvgiDvOnsD0QwRzqqbmyaw0rTQ+IBhybmv4INeuNFzeiM6+uFxwRETbVUSd476CGM5+dz1Nb5z7bgBEw2w7xULTjCFIyYmvOIfSx/2ShPpfsiRES9fL3LOau5GqFeHczjwr0nFVuAALB4xnS8cw5z9dZfawcJUOCQKTYzUpSlLvetEAYRDXdl66mPQVdG0VLtKuyxZfIFNyyifY7IaClPvZt1ZZXgr+rKRj+m+vbVU6r5eHnQTqC4m5AVRtCA97SXYPTFFR1QH8a7YWki0/sTUQKBgQD/xnpD+mZfxdexEMlVfBIjrVfcEBeky2hVNgCXDqd2oe/NKQC3vbcgDV9NslhlBTIdXvHvvLUHSSoBlK8lic/53VYUbLQtyEmEM7k5gV6zJBLudyfXgMd30Jyq6Y4w6J4UKOCy/vxOu8DVbMBG56XpnjvyoEVBCSuJXPDXSnUE2wKBgQCiNFyC9eF/r2j12K5vERIUzGH11w6T7yIcY66JKce2m1oqucyo7ZBX3HXxOUMM6676QmesMJF2/01vZrEe8usg0zFpyhKXLc9sk8nEYd5Ip9Gui2LmAsRXTzXNR7tVI4Bxueqrb7GKrOMteplMy0sze/nOAOnZbszSxiXjqsbT8wKBgDC52e77U+do5EdKIGDVqwr66eL1edueGHkrOX+Nfh+eh/V4mzdlv+4uPfqqQCa2j66CuOpn88C4knUMozUuhN1f6hcoAkc6ga7av62R1L2h4K1nK8LlOJq9tirlJX5xwjOq+et/ogdJw1mlRxf652OTDm6RU8ApBA8+Em+hMpvDAoGAZoZSMzTXY62r2jkriGhx1VOaV5mnTTpJhUg8edY+td1cEMV/5wbBxcdDhUV8bB5Ma0Kt5NiOGXklqNRv/+/rTsQu538iYQxDn42KauaxaZspnfnceSYmlEks6KP+dMIL3dZ1zga7YbwFnClx3GhjEBe8vck2BolSTaeRK2Y2ZqECgYAHBocOQA8zhUhTMaA/yPM1gP6V+bQu92wLf318OpXRMr6/DNKnoujhFCB3wsemBWrJCdpIZifdOaNQnw6ZIyPiK88q9yA8PYUBeF+KjX0mk8k8/vLoUUJqe2bf7WV+3M0jxjlBhWpeN8rFSbuMN1gEvX1dRKIs8yNbY9FBePejTw==",
- ]
- }
4、创建Sophix入口程序
- /**
- * Sophix入口类,专门用于初始化Sophix,不应包含任何业务逻辑。
- * 此类必须继承自SophixApplication,onCreate方法不需要实现。
- * 此类不应与项目中的其他类有任何互相调用的逻辑,必须完全做到隔离。
- * AndroidManifest中设置application为此类,而SophixEntry中设为原先Application类。
- * 注意原先Application里不需要再重复初始化Sophix,并且需要避免混淆原先Application类。
- * 如有其它自定义改造,请咨询官方后妥善处理。
- */
- public class SophixStubApplication extends SophixApplication {
- private final String TAG = "SophixStubApplication";
- // 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
- @Keep
- @SophixEntry(MyRealApplication.class)
- static class RealApplicationStub {}
- @Override
- protected void attachBaseContext(Context base) {
- super.attachBaseContext(base);
- // 如果需要使用MultiDex,需要在此处调用。
- // MultiDex.install(this);
- initSophix();
- }
- private void initSophix() {
- String appVersion = "0.0.0";
- 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();
- }
- }
注意:SophixEntry应指定项目中原先真正的Application(原项目里application的android::name指定的),这里用MyRealApplication指代。并且保证RealApplicationStub类名不被混淆。而SophixStubApplication的类名和包名可以自行取名。
@Keep
@SophixEntry(MyRealApplication.class)
static class RealApplicationStub {}
这里的Keep是android.support包中的类,目的是为了防止这个内部静态类的类名被混淆,因为sophix内部会反射获取这个类的SophixEntry。如果项目中没有依赖android.support的话,就需要在progurad里面手动指定RealApplicationStub不被混淆,详见下文。
把AndroidManifest里面的application改为这个新增的SophixStubApplication类:
- <application
- android:name=".SophixStubApplication"
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:supportsRtl="true"
- android:theme="@style/AppTheme">
这样便完成了新方式的初始化接入改造。
总结一下,过程一共有四个步骤:
5、配置热修复混淆
混淆配置文件proguard-rules.pro增加热修复相关配置
- #基线包使用,生成mapping.txt
- -printmapping mapping.txt
- ##生成的mapping.txt在app/build/outputs/mapping/release路径下,移动到/app路径下
- ##修复后的项目使用,保证混淆结果一致
- #-applymapping mapping.txt
- #hotfix
- -keep class com.taobao.sophix.**{*;}
- -keep class com.ta.utdid2.device.**{*;}
- -dontwarn com.alibaba.sdk.android.utils.**
- #防止inline
- -dontoptimize
- -keepclassmembers class com.cdel.sophixdemo.ModelApplication {
- public <init>();
- }
- # 如果不使用android.support.annotation.Keep则需加上此行
- # -keep class com.my.pkg.SophixStubApplication$RealApplicationStub
注意:
*生成基线包,使用
-printmapping mapping.txt
*生成补丁后的包,使用
-applymapping mapping.txt
然后把基线包的mapping文件拷贝到app下边。
两者不能同时出现。
6、查询和下载热修复补丁
// queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
SophixManager.getInstance().queryAndLoadNewPatch();
热修复补丁下载完成以后,等APP完全退出,下载APP启动的时候自动安装。
第三章 生成补丁包
生成补丁包的过程。
1)生成基线包
混淆文件中配置
*生成基线包,使用
-printmapping mapping.txt
打包生成基线包。
2)生成修复包
混淆文件中配置
*生成补丁后的包,使用
-applymapping mapping.txt
把基线包的mapping文件复制到app目录下。打包生成修复包。
3)生成补丁包
下载安装补丁环境
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
该工具提供了Windows和macOS和Linux版本,Windows下运行SophixPatchTool.exe,macOS下运行SophixPatchTool.app,Linux下(Ubuntu 16.04 64bit最佳)运行SophixPatchTool。并且需要安装Java环境且在JDK7或以上才能正常使用。
3.1.2.1 主对话框
3.1.2.3 设置对话框
3.1.2.3 生成补丁包
点击GO 按钮,生成补丁包。
sophix-patch就是生成的补丁包。
第四章 发布补丁包
HotFix提供了多种发布方式,方便您根据自身业务需要选择性使用。
HotFix提供了调试工具实现本地测试,方便您在正式发布前,在您的手机本地进行测试。
步骤如下:
HotFix提供灰度发布模式,您可以在控制台发布灰度批次,并为该批次指定灰度人数
和标签
,客户端拉取到补丁时会消耗该灰度人数,达到指定数量后,灰度批次自动置为停止状态。
1.2.1 发布人数
此项为设置最多可供设备请求到该批次更新补丁的次数。该计数以请求到更新补丁的次数为准,如:
1个设备请求到更新补丁之后,删除本地缓存再次请求成功1次,则总共会消耗掉2个次数。
1.2.2 指定标签
注:Android SDK从 3.2.7 版本开始支持设置标签,若接入的SDK低于该版本,新建灰度批次时忽略此项即可。
此项为设置灰度附带的标签条件。只有设置了对应标签的设备,才能请求到本批次的更新补丁。如:
端上设置标签为["tag1"], 发布时指定标签为["tag1"], 能拉取到;
端上设置标签为["tag1","tag2"], 发布时指定标签为["tag1"], 能拉取到;
端上设置标签为["tag1"], 发布时指定标签为["tag1","tag2"], 能拉取到;
端上设置标签为["tag1","tag3"], 发布时指定标签为["tag1", "tag3"], 能拉取到;
可以看到,只要端上设置的标签[组],和发布灰度批次时指定的标签[组],交集不为空,就能拉取到更新补丁。
特别注意:
1. 输入标签后,按回车,该标签输入才算成功;您可以通过多次输入,多次回车,来实现输入标签组;
2. 不输入任何标签,则该批次不会对端上携带的标签做任何校验;
1.2.3 后置操作
发布灰度批次后可以根据实际需要停止灰度批次,停止后可以选择:
2.9 发布回滚
。
HotFix提供全量发布模式,选择全量发布后,将对所有安装了当前应用版本(即之前创建应用时所填写的应用版本号)的设备推送该补丁。
与灰度发布类似,在全量发布会可以根据自身需要停止本次全量发布,停止发布后可以选择:
2.9 发布回滚
。
HotFix提供停止发布功能,用户停止某个发布批次后,系统将停止该批次补丁的继续发布,但已加载该补丁的设备会依然保持安装该补丁的状态。
HotFix提供发布回滚功能,用户选择回滚的目标补丁后,确认回滚后,所有该应用版本下设备都会获取到该目标补丁,从而实现回滚。
使用回滚功能必需要具备以下条件:
全量发布
的历史版本。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。