以往当Android App出现bug的时候,甚至仅仅是修改一行代码,都要重新发布新版本对bug进行修复,这样带来的缺点是明显的,需要用户重新升级app,覆盖率太慢,成本太高。所以就出现了热修复技术,通过打补丁的方式,通过从服务器下载补丁包,然后对有问题的类中出问题的方法,进行替换,优点是用户无感知修复,无需下载新的应用,代价小。对比其他的热修复方案,来耍一耍阿里-Sophix 。
介绍
“冷热”
- 插件化 - apk 分为宿主和插件部分,插件在需要的时候才加载进来
- 热修复 – 更新的类或者插件粒度较小的时候,我们会称之为热修复,一般用于修复bug
- 热更新 – 2016 Google 的 Android Studio 推出了Instant Run 功能 同时提出了3个名词
- 热部署 – 方法内的简单修改,无需重启app和Activity。
- 暖部署 – app无需重启,但是activity需要重启,比如资源的修改。
- 冷部署 – app需要重启,比如继承关系的改变或方法的签名变化等。
热修复特点
- 无需重新发版,实时高效热修复
- 用户无感知修复,无需下载新的应用,无需重装App,代价小
- 修复成功率高,把损失降到最低
阿里热修复方案对比
方案对比 | Andfix开源版本 | 阿里Hotfix 1.X | 阿里Hotfix最新版 (Sophix) |
---|---|---|---|
方法替换 | 支持,除部分情况[0] | 支持,除部分情况 | 全部支持 |
方法增加减少 | 不支持 | 不支持 | 以冷启动方式支持[1] |
方法反射调用 | 只支持静态方法 | 只支持静态方法 | 以冷启动方式支持 |
即时生效 | 支持 | 支持 | 视情况支持[2] |
多DEX | 不支持 | 支持 | 支持 |
资源更新 | 不支持 | 不支持 | 支持 |
so库更新 | 不支持 | 不支持 | 支持 |
Android版本 | 支持2.3~7.0 | 支持2.3~6.0 | 全部支持包含7.0以上 |
已有机型 | 大部分支持[3] | 大部分支持 | 全部支持 |
安全机制 | 无 | 加密传输及签名校验 | 加密传输及签名校验 |
性能损耗 | 低,几乎无损耗 | 低,几乎无损耗 | 低,仅冷启动情况下有些损耗 |
生成补丁 | 繁琐,命令行操作 | 繁琐,命令行操作 | 便捷,图形化界面 |
补丁大小 | 不大,仅变动的类 | 小,仅变动的方法 | 不大,仅变动的资源和代码[4] |
服务端支持 | 无 | 支持服务端控制[5] | 支持服务端控制 |
说明:
- [0] 部分情况指的是构造方法、参数数目大于8或者参数包括long,double,float基本类型的方法。
- [1] 冷启动方式,指的是需要重启app在下次启动时才能生效。
- [2] 对于Andfix及Hotfix 1.X能够支持的代码变动情况,都能做到即时生效。而对于其他代码变动较大的情况,会走冷启动方式,此时就无法做到即时生效。
- [3] Hotfix 1.X已经支持绝大部分主流手机,只是在X86设备以及修改了虚拟机底层结构的ROM上不支持。
- [4] 由于支持了资源和库,如果有这些方面的更新,就会导致的补丁变大一些,这个是很正常的。并且由于只包含差异的部分,所以补丁已经是最大程度的小了。
- [5] 提供服务端的补丁发布和停发、版本控制和灰度功能,存储开发者上传的补丁包。
其他热修复方案
方案 | 作者 |
---|---|
Tinker | 微信(apk补丁) |
Robust | 美团 |
Amigo | 饿了么(apk补丁) |
Nuwa | 个人开发者 |
Dexposed | |
RocooFix | 个人开发者 |
集成Sophix
注册阿里云账号
- 注册完开发者账号,成功登录后进入控制台,添加移动热修复服务。
客户端集成
-
引入maven依赖仓库
在项目app下的build.gradle中添加maven仓库地址和版本依赖-
添加maven仓库地址:
repositories { maven { url "http://maven.aliyun.com/nexus/content/repositories/releases" } }
-
添加依赖:
compile 'com.aliyun.ams:alicloud-android-hotfix:3.1.2'
-
-
添加使用权限
<! -- 网络权限 --> <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"/>
-
配置AndroidManifest文件
在application节点里添加配置,用之前在阿里云上创建的App的配置信息AppId、APPSecret、RSA密钥替换value的值:<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密钥" /> ··· </application>
- Application接入SDK
其他接口使用请查看SDK文档/** * 初始化Sophix */ private void initSophix() { String appVersion; try { appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; } catch (Exception e) { e.printStackTrace(); appVersion = "1.0.0"; } SophixManager.getInstance().setContext(this).setAppVersion(appVersion).setAesKey(null).setEnableDebug(true).setPatchLoadStatusStub(new PatchLoadStatusListener() { @Override public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) { // 补丁加载回调信息 StringBuilder msg = new StringBuilder(); msg.append("Mode:").append(mode).append("\n"); msg.append("Code:").append(code).append("\n"); msg.append("Info:").append(info).append("\n"); msg.append("HandlePatchVersion:").append(handlePatchVersion).append("\n"); if (mDisplayListener != null) mDisplayListener.handle(msg.toString()); // 补丁加载回调通知 switch (code) { case PatchStatus.CODE_LOAD_SUCCESS: // 表明补丁加载成功 break; case PatchStatus.CODE_LOAD_RELAUNCH: // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启; // 建议: 用户可以监听进入后台事件,然后调用killProcessSafely自杀 // 注意:不可以直接Process.killProcess(Process.myPid())来杀进程,这样会扰乱Sophix的内部状态。 break; case PatchStatus.CODE_LOAD_FAIL: // 内部引擎异常,推荐此时清空本地补丁,防止失败补丁重复加载 SophixManager.getInstance().cleanPatches(); break; default: // 其它错误信息,查看PatchStatus类说明 break; } } }).initialize(); // 加载新的补丁包 SophixManager.getInstance().queryAndLoadNewPatch(); }
至此,Sophix配置完成。
测试
- 客户端第一版本,如图,打包成Sophix_V1.apk
-
生成补丁,生成补丁文档传送门
Windows下载阿里补丁工具SophixPatchTool,运行SophixPatchTool.exe,添加包,如果有签名等设置,则点击设置,配置相应的签名等,然后点击“Go”,生成补丁,即sophix-patch.jar:
-
上传补丁
进入阿里云热修复App管理的Android平台里,即查看AppId、APPSecret、RSA密钥那个页面,添加新版本,成功添加版本后,点击查看详情进入,上传刚刚生成的sophix-patch.jar补丁。上传补丁
-
本地测试
安装Sophix_V1.apk,同时将补丁sophix-patch.jar放到Android设备的目录里:/sdcard/sophix-patch.jar
,下载hotfixdebug工具,安装后,打开进入调试apk,配置如下:
- 发布
进入阿里云的补丁详情页面,点击发布。再次进行调试,这次不用Sophix调试工具;先卸载已安装的Sophix_V1,重新安装,打开后再次等待检测补丁更新,再次出现提示ok。
推广
有兴趣的童鞋可以看看阿里出品的热修复原理宝典