当前位置:   article > 正文

阿里热修复Sophix

阿里热修复sophix

第一章、准备工作
1、申请阿里云账号;

2、开通阿里云移动管理服务;

3、开通阿里云移动服务平台EMAS.

4、创建一个新产品,即需要接入的APP产品。

 

第二章:接入热修复SDK

您可以在应用管理页面获取配置SDK所需要的基本信息。包括:

  • AppKey:用于AppKey是阿里云上应用的唯一标识,热修复的appId可设置AppKey。
  • RSA密钥: RSA密钥是保存在客户端本地用于解密patch包过程中使用的解密密钥。(推荐使用chrome浏览器下载)
  • AppSecret:用于URL请求时生成合法验签标识的key。

Demo程序下载地址:

https://github.com/aliyun/alicloud-android-demo

安卓Demon:

https://github.com/joedan0104/SophixDemo

1、添加热修复依赖库

在项目的app的build.gradle中添加Maven仓库

  1. repositories {
  2.    maven {
  3.        url "http://maven.aliyun.com/nexus/content/repositories/releases"
  4.    }
  5. }

在dependencies增加热修复库坐标版本依赖
compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.8'

2、AndroidManifest增加需要的权限

包括读写SD卡、网络权限。

  1. <! -- 网络权限 -->
  2. <uses-permission android:name="android.permission.INTERNET" />
  3. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  4. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  5. <! -- 外部存储读权限,调试工具加载本地补丁需要 -->
  6. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

3、配置APP热修复相关数据

在AndroidManifest的application节点下,配置热修复字段。

  1. <!-- 热修复字段 -->
  2. <meta-data
  3. android:name="com.taobao.android.hotfix.IDSECRET"
  4. android:value="${HOTFIX_APPID}" />
  5. <meta-data
  6. android:name="com.taobao.android.hotfix.APPSECRET"
  7. android:value="${HOTFIX_APPSECRET}" />
  8. <meta-data
  9. android:name="com.taobao.android.hotfix.RSASECRET"
  10. android:value="${HOTFIX_RSA}" />

这些字段在编译的时候写入具体的值。

这几个值的阿里云控制台用户创建的APP对应的热修复的值。

其中APPID:对应的AppKey

APPSECRET:对应的AppSecret

RSA:对应的Rsa

  1. def config = rootProject.ext// android基本配置
  2. android {
  3. compileSdkVersion config.android.compileSdkVersion
  4. buildToolsVersion config.android.buildToolsVersion
  5. defaultConfig {
  6. applicationId "com.cdel.sophixdemo"
  7. minSdkVersion config.android.minSdkVersion
  8. targetSdkVersion config.android.targetSdkVersion
  9. versionCode 1
  10. versionName "1.0.1"
  11. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  12. // dex突破65535的限制
  13. multiDexEnabled true
  14. //个别机器添加热修复导致Vitamio 崩溃问题
  15. ndk {
  16. abiFilters "armeabi", "armeabi-v7a"
  17. }
  18. // AndroidManifest替换参数
  19. manifestPlaceholders = [
  20. HOTFIX_APPID : "25994860",
  21. HOTFIX_APPSECRET : "f63fcee692a46eb81da4c7a10fe1cd4f",
  22. 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==",
  23. ]
  24. }

4、创建Sophix入口程序

  1. /**
  2. * Sophix入口类,专门用于初始化Sophix,不应包含任何业务逻辑。
  3. * 此类必须继承自SophixApplication,onCreate方法不需要实现。
  4. * 此类不应与项目中的其他类有任何互相调用的逻辑,必须完全做到隔离。
  5. * AndroidManifest中设置application为此类,而SophixEntry中设为原先Application类。
  6. * 注意原先Application里不需要再重复初始化Sophix,并且需要避免混淆原先Application类。
  7. * 如有其它自定义改造,请咨询官方后妥善处理。
  8. */
  9. public class SophixStubApplication extends SophixApplication {
  10. private final String TAG = "SophixStubApplication";
  11. // 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。
  12. @Keep
  13. @SophixEntry(MyRealApplication.class)
  14. static class RealApplicationStub {}
  15. @Override
  16. protected void attachBaseContext(Context base) {
  17. super.attachBaseContext(base);
  18. // 如果需要使用MultiDex,需要在此处调用。
  19. // MultiDex.install(this);
  20. initSophix();
  21. }
  22. private void initSophix() {
  23. String appVersion = "0.0.0";
  24. try {
  25. appVersion = this.getPackageManager()
  26. .getPackageInfo(this.getPackageName(), 0)
  27. .versionName;
  28. } catch (Exception e) {
  29. }
  30. final SophixManager instance = SophixManager.getInstance();
  31. instance.setContext(this)
  32. .setAppVersion(appVersion)
  33. .setSecretMetaData(null, null, null)
  34. .setEnableDebug(true)
  35. .setEnableFullLog()
  36. .setPatchLoadStatusStub(new PatchLoadStatusListener() {
  37. @Override
  38. public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
  39. if (code == PatchStatus.CODE_LOAD_SUCCESS) {
  40. Log.i(TAG, "sophix load patch success!");
  41. } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
  42. // 如果需要在后台重启,建议此处用SharePreference保存状态。
  43. Log.i(TAG, "sophix preload patch success. restart app to make effect.");
  44. }
  45. }
  46. }).initialize();
  47. }
  48. }

注意: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类:

  1. <application
  2. android:name=".SophixStubApplication"
  3. android:allowBackup="true"
  4. android:icon="@mipmap/ic_launcher"
  5. android:label="@string/app_name"
  6. android:roundIcon="@mipmap/ic_launcher_round"
  7. android:supportsRtl="true"
  8. android:theme="@style/AppTheme">

这样便完成了新方式的初始化接入改造。

总结一下,过程一共有四个步骤:

  1. 把此SophixStubApplication入口类添加进项目中,所有Sophix相关初始化放在此类中。并且不应包含开发者的任何业务逻辑代码。 若使用了MultiDex,也应在SophixStubApplication的initSophix之前添加,并且需要记得在原来的Application里面去除MultiDex,避免重复调用导致问题。
  2. 把RealApplicationStub的SophixEntry注解的内容改为自己原先真正的MyRealApplication类。
  3. 混淆文件中确保某些内容不被混淆。
  4. AndroidManifest里面的application改为新增的SophixStubApplication入口类。

5、配置热修复混淆

混淆配置文件proguard-rules.pro增加热修复相关配置

  1. #基线包使用,生成mapping.txt
  2. -printmapping mapping.txt
  3. ##生成的mapping.txt在app/build/outputs/mapping/release路径下,移动到/app路径下
  4. ##修复后的项目使用,保证混淆结果一致
  5. #-applymapping mapping.txt
  1. #hotfix
  2. -keep class com.taobao.sophix.**{*;}
  3. -keep class com.ta.utdid2.device.**{*;}
  4. -dontwarn com.alibaba.sdk.android.utils.**
  5. #防止inline
  6. -dontoptimize
  7. -keepclassmembers class com.cdel.sophixdemo.ModelApplication {
  8. public <init>();
  9. }
  10. # 如果不使用android.support.annotation.Keep则需加上此行
  11. # -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)生成补丁包

下载安装补丁环境

3.1.1 下载打包工具

patch补丁包生成需要使用到打补丁工具SophixPatchTool, 如还未下载打包工具,请前往下载Android打包工具。

该工具提供了Windows和macOS和Linux版本,Windows下运行SophixPatchTool.exe,macOS下运行SophixPatchTool.app,Linux下(Ubuntu 16.04 64bit最佳)运行SophixPatchTool。并且需要安装Java环境且在JDK7或以上才能正常使用。

3.1.2 生成Patch

3.1.2.1 主对话框

sophix1

  • 旧包:<必填> 选择基线包路径(有问题的APK)。
  • 新包:<必填> 选择新包路径(修复过该问题APK)。
  • 日志:打开日志输出窗口。
  • 高级:展开高级选项,见1.2.2。
  • 设置:配置其他信息。
  • GO!:开始生成补丁。

3.1.2.3 设置对话框

tool

  • 补丁输出路径:<必填> 指定生成补丁之后补丁的存放位置,必须是已存在的目录。
  • Key Store Path:<选填>本地的签名文件的路径,不输入则不做签名。如果基线包是签名包,此处需要选择keystore文件。如果用户的keystore文件显示不出来,可以将原来keystore的文件拷贝一份,重命名为keystore.xxx,这样就可以显示出来。
  • Key Store Password:<选填>证书文件的密码。Key Store Path设置时必填
  • Key Alias:<选填>Key的别名。Key Store Path设置时必填
  • Key Passwrod:<选填>Key的密码。Key Store Path设置时必填
  • AES Key:<选填>自定义aes秘钥, 必须是16位数字或字母的组合。必须与setAesKey中设置的秘钥一致。可不填。
  • Filter Class File:<选填>本地的白名单类列表文件的路径,放进去的类不会再计算patch,文件格式: 一行一个类名。

3.1.2.3 生成补丁包

点击GO 按钮,生成补丁包。

sophix-patch就是生成的补丁包。

第四章 发布补丁包

发布补丁


HotFix提供了多种发布方式,方便您根据自身业务需要选择性使用。

  • 上传补丁后,会展示补丁列表信息,点击“详情”,进入发布页面

patch_details

  • 进入详情页面,点击“新建发布”,进入发布流程

新建发布

 

1.1 本地测试

HotFix提供了调试工具实现本地测试,方便您在正式发布前,在您的手机本地进行测试。

步骤如下:

1.2 灰度发布

HotFix提供灰度发布模式,您可以在控制台发布灰度批次,并为该批次指定灰度人数标签,客户端拉取到补丁时会消耗该灰度人数,达到指定数量后,灰度批次自动置为停止状态。

发布灰度批次

1.2.1 发布人数

此项为设置最多可供设备请求到该批次更新补丁的次数。该计数以请求到更新补丁的次数为准,如:

试用

 
  1. 1个设备请求到更新补丁之后,删除本地缓存再次请求成功1次,则总共会消耗掉2个次数。

1.2.2 指定标签

注:Android SDK从 3.2.7 版本开始支持设置标签,若接入的SDK低于该版本,新建灰度批次时忽略此项即可。

此项为设置灰度附带的标签条件。只有设置了对应标签的设备,才能请求到本批次的更新补丁。如:

试用

 
  1. 端上设置标签为["tag1"], 发布时指定标签为["tag1"], 能拉取到;
  2. 端上设置标签为["tag1","tag2"], 发布时指定标签为["tag1"], 能拉取到;
  3. 端上设置标签为["tag1"], 发布时指定标签为["tag1","tag2"], 能拉取到;
  4. 端上设置标签为["tag1","tag3"], 发布时指定标签为["tag1", "tag3"], 能拉取到;

可以看到,只要端上设置的标签[组],和发布灰度批次时指定的标签[组],交集不为空,就能拉取到更新补丁。

特别注意:

1. 输入标签后,按回车,该标签输入才算成功;您可以通过多次输入,多次回车,来实现输入标签组;

2. 不输入任何标签,则该批次不会对端上携带的标签做任何校验;

1.2.3 后置操作

发布灰度批次后可以根据实际需要停止灰度批次,停止后可以选择:

  • 发布新的灰度批次;
  • 发布新的全量批次;
  • 回滚版本(如果存在历史版本)见 2.9 发布回滚

 

1.3 全量发布

HotFix提供全量发布模式,选择全量发布后,将对所有安装了当前应用版本(即之前创建应用时所填写的应用版本号)的设备推送该补丁。

与灰度发布类似,在全量发布会可以根据自身需要停止本次全量发布,停止发布后可以选择:

  • 继续全量发布。
  • 回滚版本(如果存在历史已经发布过全量批次的版本),见2.9 发布回滚

 

1.4 停止发布

HotFix提供停止发布功能,用户停止某个发布批次后,系统将停止该批次补丁的继续发布,但已加载该补丁的设备会依然保持安装该补丁的状态。

 

1.5 发布回滚

HotFix提供发布回滚功能,用户选择回滚的目标补丁后,确认回滚后,所有该应用版本下设备都会获取到该目标补丁,从而实现回滚。

使用回滚功能必需要具备以下条件:

  • 该版本之前存在至少一个全量发布的历史版本。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/744009
推荐阅读
相关标签
  

闽ICP备14008679号