阅读本文大概需要10分钟。
其实热修复已经出来很久了,其中包含了很多的厂家的热修复方案,包含收费与免费,集成简单与集成复杂以及一些其他的区别性。综合考虑下选择了阿里的spohix修复方案,这里主要是简单的记录下修复的一些大概步骤,以及包含自己利用sophix加载本地的补丁包内容。
---------------------------------------------------------------分割线---------------------------------------------------------------
tips:
关于版本控制,形式为采取先修复新补丁,然后把旧补丁删掉, 每次打补丁需要基于初始版本进行打补丁
目前已知的一些问题:
1.修复不支持kotlin的协程,如果你的代码中包含协程内容,修复后的应用会崩溃
------------------------------------------------------------------。---------------------------------------------------------------
大致步骤如下:
- 在阿里云控制台注册你的应用,拿到对应的几个key密钥,这几个密钥后面需要放到你的应用中作为识别的一种标志
- 依赖(下载)sdk,集成到应用中
- 选择接入方式(目前有快速接入【对android新版本可能有兼容性问题】和稳健接入),这里采用稳健接入的方式说明
- 使用sdk中的application替换自己原先的application节点(自己application不用动,到时候放进sdk的application的就好了)
- 其实做完上面的步骤就已经ok了,如果需要个性化处理自己再整(比如再什么情况下才去拉取热修复补丁包,或者通过加载本地的补丁包来绕过收费(其实理论上来讲是可行的))
友情提示:sophix免费版的阈值:1,每个账号每月5万台设备免费;2,每个账号下的每个应用平均到每台设备,1天免费查询补丁20次
ok,进入正文:
第一步:注册应用,点击链接进去自己注册
第二步:依赖,在需要用到的项目下的build.gradle 文件中添加api 'com.aliyun.ams:alicloud-android-hotfix:3.2.8'
然后编译下就可以了
第三步:application的替换,如果你的项目里有用到自己的application,需要替换成sophix的,在官方接入文档里有这个类,这里也同步贴下
//在manifest文件中的application节点应该用这一个节点 //同时需要注意,在该类里必须所有用到的类都是android原生的,不能用到你自己创建出来的类,不然打补丁会失败 public class SophixStubApplication extends SophixApplication { private final String TAG = "SophixStubApplication"; // 此处SophixEntry应指定真正的Application,并且保证RealApplicationStub类名不被混淆。 //这里这个myapplication就是你原先的那个application @Keep @SophixEntry(MyApplication.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) { Log.e(TAG,"sophix 获取版本号异常:" + e); e.printStackTrace(); } final SophixManager instance = SophixManager.getInstance(); instance.setContext(this) .setAppVersion(appVersion) //设置一些配置信息,idSecret, appSecret, rsaSecret .setSecretMetaData("","","") .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.e(TAG,"sophix 补丁加载成功"); } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) { // 如果需要在后台重启,建议此处用SharePreference保存状态。 // 建议: 用户可以监听进入后台事件, 然后调用killProcessSafely自杀,以此加快应用补丁,>详见1.3.2.3 Log.e(TAG, "sophix 加载成功,但是需要重启后才能生效"); } else { Log.e(TAG, "other msg code:" + code); } } }) .initialize(); //调用这行代码一次,sdk 就回去控制台拉取查询一次,需要注意的是免费阈值只有20次,需要有一些方式来控制,比如先从自己平台查一遍有没有补丁包,如果有的话再调用这行带去去控制台拉补丁包下载,这样能极大减少阈值的使用 SophixManager.getInstance().queryAndLoadNewPatch();}
第四步:生成补丁,验证是否集成成功。打包俩个包,新包和旧包,利用工具 进行生成差异补丁包,把补丁包上传到控制台下发,然后应用重新进入触发sdk的拉取操作进行修复。
前面有讲到通过加载本地补丁包来绕过收费的方式,这里进行特殊讲解一下。
其实本质上spohix是支持本地加载补丁包的,但是翻了一圈没有找到对应的api处理,提了工单问对应的技术人员的回复是:“需要买,买了以后给你这种特殊方式操作,你就可以完全不通过阿里控制台进行下发补丁了”,但是其实细心点可以发现,他提供的调试demo是支持本地加载补丁包的,但是!!!很坑爹的来了,他这个调试apk工具是没加本地文件读取的权限申请,所以就导致了调试工具无法加载本地补丁包,别问我为啥知道的,我把这个apk反编译了以后看到的,manifest文件里就没有文件读取的权限内容。通过反编译+一步步的分析他的代码,找到了它里面进行加载本地补丁包的方式,具体方式如下:
//注意这个导包,因为他里面都是混效后的代码,所以最终如果加载本地补丁包的话,形式上就是a.e.x这样子的调用了
import com.taobao.sophix.a.e;
//下面就是完整的代码了,第一个参数是补丁包在手机里的绝对位置,第二个就是修复的回调,和上面application里面的那个一样
((e)SophixManager.getInstance()).a("", new PatchLoadStatusListener() {
@Override
public void onLoad(int mode, int code, String info, int handlePatchVersion) {
}
});
//注意:这种方式的修复,在3.2.8的spohix版本上试过是可以的,换了版本的话可能就不行了,因为毕竟换了版本会重新混淆,之后的话一些.a.e啥的也会变
ok,本文结束。