移动热修复Sophix之初体验

来源:互联网 发布:巴哥犬价格知乎 编辑:程序博客网 时间:2024/05/29 16:35

在我们刚刚发布出去的APK包有紧急BUG需要修复,传统的处理流程如下:

采用热修复技术,你可以把补丁上传到云端,APP直接从云端下拉补丁,修正BUG。这时的处理流程如下:

可见热修复技术具有无需重新安装,用户无感知,体验好,修复成功率高等优点。

Sophix是阿里云在20176月发布的移动热修复解决方案,是HotFix的升级版从官方文档中我们可以了解到Sophix具有如下优势。

  • 补丁即时生效,不需要应用重启;
  • 补丁包同样采用差量技术,生成的PATCH体积小;
  • 对应用无侵入,几乎无性能损耗;
  • 傻瓜式接入。


1. 创建应用

登录MHub控制台:https://mhub.console.aliyun.com/点击右上角的创建APP。

 

创建成功后选择“产品与服务” ---> “移动热修复”可查看刚刚创建的应用。

 

点击“管理”可查看应用信息。

 

AppIdAppSecretRSA密钥在我们APP的配置中需要。

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

2. 集成Sophix

2.1 build.gradle文件配置

app的build.gradle文件中添加如下配置:

repositories {    maven {        url "http://maven.aliyun.com/nexus/content/repositories/releases"    }}dependencies {    ...    compile 'com.aliyun.ams:alicloud-android-hotfix:3.0.6'}

2.2 Manifest文件配置

AndroidManifest.xml中添加权限。

<!-- 网络权限 --><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以上的运行时权限获取。

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密钥" />

App IDApp SecretRSA密钥在上文中已经获取。

2.3 混淆配置

appproguard-rules.pro文件中添加如下配置:

#基线包使用,生成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.**{*;}

2.4 SDK初始化

Application.attachBaseContext()Application.onCreate()的最开始初始化SDK,建议放在attachBaseContext最前面。

@Overrideprotected void attachBaseContext(Context base) {    super.attachBaseContext(base);    initHotfix();}private void initHotfix() {    String appVersion;    try {        appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;    } catch (Exception e) {        appVersion = "1.0.0";    }    SophixManager.getInstance().setContext(this)            .setAppVersion(appVersion)            .setAesKey(null)            //.setAesKey("0123456789123456")            .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) {                        // 表明补丁加载成功                    } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {                        // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启;                        // 建议: 用户可以监听进入后台事件, 然后应用自杀                    } else if (code == PatchStatus.CODE_LOAD_FAIL) {                        // 内部引擎异常, 推荐此时清空本地补丁, 防止失败补丁重复加载                         SophixManager.getInstance().cleanPatches();                    } else {                        // 其它错误信息, 查看PatchStatus类说明                    }                }            }).initialize();}

initialize(): <必选>

setContext(application): <必选> 传入入口Application即可

setAppVersion(appVersion): <必选> 应用的版本号

setSecretMetaData(idSecret, appSecret, rsaSecret): <可选> 三个Secret分别对应AndroidManifest里面的三个,可以不在AndroidManifest设置而是用此函数来设置Secret。放到代码里面进行设置可以自定义混淆代码,更加安全,此函数的设置会覆盖AndroidManifest里面的设置,如果对应的值设为null,默认会在使用AndroidManifest里面的。

setEnableDebug(true/false): <可选> 默认为false, 是否调试模式, 调试模式下会输出日志以及不进行补丁签名校验. 线下调试此参数可以设置为true, 查看日志过滤TAG:Sophix, 同时强制不对补丁进行签名校验, 所有就算补丁未签名或者签名失败也发现可以加载成功. 但是正式发布该参数必须为false, false会对补丁做签名校验, 否则就可能存在安全漏洞风险

setAesKey(aesKey): <可选> 用户自定义aes秘钥, 会对补丁包采用对称加密。这个参数值必须是16位数字或字母的组合,是和补丁工具设置里面AES Key保持完全一致, 补丁才能正确被解密进而加载。此时平台无感知这个秘钥, 所以不用担心阿里云移动平台会利用你们的补丁做一些非法的事情。

setPatchLoadStatusStub(new PatchLoadStatusListener()): <可选> 设置patch加载状态监听器, 该方法参数需要实现PatchLoadStatusListener接口

setUnsupportedModel(modelName, sdkVersionInt):<可选> 把不支持的设备加入黑名单,加入后不会进行热修复。modelName为该机型上Build.MODEL的值,这个值也可以通过adb shell getprop | grep ro.product.model取得。sdkVersionInt就是该机型的Android版本,也就是Build.VERSION.SDK_INT,若设为0,则对应该机型所有安卓版本。

2.5 拉取补丁

补丁在后台发布之后, 并不会主动下行推送到客户端,需要手动调用queryAndLoadNewPatch()方法查询服务器是否有新的可用补丁SDK内部限制连续两次queryAndLoadNewPatch()方法调用不能短于3s,否则的话就会报code:19的错误码

3、补丁工具的使用

3.1 下载打包工具

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

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

3.2 生成Patch


  • 旧包:<必填> 选择基线包路径(有问题的APK)。

  • 新包:<必填> 选择新包路径(修复过该问题APK)。

  • 设置:配置其他信息。

  • 补丁输出路径:<必填>指定生成补丁之后补丁的存放位置,必须是已存在的目录。

  • Key Store Path<选填>本地的签名文件的路径,不输入则不做签名。

  • Key Store Password<选填>证书文件的密码。

  • Key Alias<选填>Key的别名。

  • Key Passwrod<选填>Key的密码。

  • AES Key<选填>自定义aes秘钥,必须是16位数字或字母的组合。必须与setAesKey中设置的秘钥一致。

  • Filter Class File<选填>本地的白名单类列表文件的路径,放进去的类不会再计算patch,文件格式:一行一个类名。

注意:生成的补丁文件名为sophix-patch.jar,不可更改!

4、上传补丁文件

登录MHub控制台:https://mhub.console.aliyun.com/点击APP列表中的“管理”。



Demo下载

参考文档:

https://www.aliyun.com/product/hotfix

《深入探索Android热修复技术原理》