转载《Android热更新之初探》

luciandun 23 14:17* 字数 1466 阅读 2518 评论 0
什么是热修复?

热修复提出于2014年,兴起于2016年,尤其是在Instant run 问世以后,各种热修复技术相继涌出。
是一种摆脱传统发版方案直接使用补丁来更新app内容,不需要重新下载安装apk等略过一系列繁琐过程的新兴技术,目前国内部分成熟App都拥有自己的热修复技术,如:手淘、QQ、微信、美团、饿了么等。

热修复有什么优势&为什么要使用热修复?

来看一个场景:公司一个项目A在上线后发现一个严重bug如果不紧急修复可能导致用户流失,这种情况下如果是传统的app更新就很麻烦了大概是这个流程:



这期间重新发版涉及到提交测试环节,这样修复一个bug很不及时,如果使用热修复方案,它将变得很简单:



其优势为:

  • 无需重新发版,简单高效
  • 用户无感知,无需下载新应用,代价小
  • 修复成功率高,挽回用户群体
热修复是如何工作的?
  • 2017年6月手淘联合阿里云正式发布了新一代非侵入式Android热修复方案 - Sophix
    它能修复:代码、资源、SO库,下图为Sophix与微信和饿了么热修复技术对比表


从表中我们能知道个大概,就是Sophix似乎更值得使用一下。
分别介绍QQ空间超级不定、微信Tinker和Sophix的前身HotFix各自的工作原理。

首先了解一下apk的执行过程:代码被编译Build后生成apk文件,其实在里面生成了一个classes.dex文件。

我们解压一个apk文件如下图:



这个classes.dex就是所有代码的集合,是一个可执行文件,android运行apk实质是解压apk运行里面的这个的dex文件。
apk首次运行的时候会对这个dex文件进行优化,优化后生成一个odex文件,存在于缓存中,下次再启动就直接打开这个odex文件,达到快速打开目的。而执行apk的过程就是遍历这个dex并作出相应操作的过程,遍历后的dex方法存放在一个Elements数组中,它的长度限制是65536.即日常说的65K.
如果我们apk因为太庞大或者是引用三方库太多导致方法数超过65K,就会报错.
而谷歌已经在Android 5.0开始支持Multdex.

在知道上面信息后,我们谈谈这三家的热修复是如何实现的
1.QQ空间超级补丁:基于DEX分包方案,使用了多DEX加载的原理,大致的过程就是:把BUG方法修复以后,放到一个单独的DEX里,插入到dexElements数组的最前面,让虚拟机去加载修复完后的方法。



当patch.dex中包含Test.class时就会优先加载,在后续的DEX中遇到Test.class的话就会直接返回而不去加载,这样就达到了修复的目的.

2.微信Tinker:微信针对QQ空间超级补丁技术的不足提出了一个提供DEX差量包,整体替换DEX的方案。主要的原理是与QQ空间超级补丁技术基本相同,区别在于不再将patch.dex增加到elements数组中,而是差量的方式给出patch.dex,然后将patch.dex与应用的classes.dex合并,然后整体替换掉旧的DEX文件,以达到修复的目的。



3.AndFix:不同于QQ空间超级补丁技术和微信Tinker通过增加或替换整个DEX的方案,提供了一种运行时在Native修改Filed指针的方式,实现方法的替换,达到即时生效无需重启,对应用无性能消耗的目的。

AndFix与HotFix的关系如下:


AndFix实现原理:


AndFix实现过程:


更详细的说明戳这里:三大流派之简单对比

阿里云Sophix热修复之简单使用
Sophix集成示例:
第一步:找到Project的build.gradle文件,在allProjects节点下加上如下代码:
repositories {
          maven { url"http://maven.aliyun.com/nexus/content/repositories/releases"}
}
第二步:找到Module的build.gradle文件,添加依赖:

compile'com.aliyun.ams:alicloud-android-hotfix:3.0.7'
然后同步project

第三步:添加权限,SDK使用到以下权限
  <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以上的运行时权限获取

第四步:密钥等配置,在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密钥" />
第五步:登录阿里云热修复管理控制台,填入对应3个value
第六步:代码集成

在Application的attachBaseContext方法里加入Sophix初始化

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        SophixManager.getInstance().setContext(this)
                .setAppVersion(getAppVersion())
                .setAesKey(null)
                .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();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        ......
       // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
        SophixManager.getInstance().queryAndLoadNewPatch();
}

自此SDK的集成已经差不多完成,官方给出了很详细的集成方法,官方集成文档

第七步:生成热修复补丁

我们直接看官方文档这里面写的很详细,细到每个设置每个参数都有说明

第八步:调试并发布补丁

首先我们需要上传补丁到阿里云管理后台,点此查看详细操作
接下来是对补丁的调试,点此查看详细操作
调试没毛病后,发布补丁,参考管理后台使用说明的step5

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值