美文网首页
Android热修复系列(一):认识篇

Android热修复系列(一):认识篇

作者: 在一颗大大大榕树下 | 来源:发表于2019-03-06 16:57 被阅读0次

    前言

    本文是基于《深入探索Android热修复技术原理》一书,所做的归纳总结;本篇是基于热修复一些简单原理非常感谢阿里团队的技术分享,让我们开始吧!

    Q1. 什么是热修复?

    我们都知道项目出现BUG,修复完成之后需要重新打包发布新版本,并让用户下载更新才能修复应用。这套操作用户体验很差,非常差。so,技术大佬们就把热修复给整了出来,对此我只能说,tql!

    图1 热修复流程
    热修复的优势:
    • 无需发布新版本,实时高效
    • 无感知修复,无需下载应用,用户体验好
    • 修复成功率高
    图2 热修复各维度比较
    Q2. 能修复些什么?
    • 代码修复
    • 资源修复
    • so库修复

    part 1. 代码修复

    代码修复主要有两种方案:底层替换方案和类加载方案

    两种方案的优劣势:

    • 底层替换方案限制多,但是时效性好,加载轻快,立即见效
    • 类加载方案时效性差,需要冷启动才能修复,但是修复范围广,限制少
    底层替换方案:
    • 已经加载的类中替换掉原来的方法,基于原有的类修改。
    • 既然是基于原有的类,这个方案无法对类中方法和字段进行增减,因为这样会破坏类的结构。

    如果补丁中的类出现方法增加或者减少,会导致这个类以及整个Dex中方法数发生变化,方法索引也会随之改变,就无法根据索引找到正确的方法了;而类中字段出现增减也是相同的情况,字段索引会产生混乱,在访问新增字段时会产生不可预期的效果。

    Sophix:传统底层替换方案是从虚拟机底层修改字段实现的,各个手机厂商之间系统底层可能会产生差异,产生兼容问题。Sophix忽略了底层的ArtMethod的差异,克服了这一限制。

    类加载方案:
    • 应用重新启动时,让ClassLoader去加载新的类。
    • 因为在应用运行到中途,所需要加载的新类在虚拟机中已经被加载过了。旧的对象还在虚拟机中,是无法加载新类的。所以,需要应用重新启动,还没走到业务逻辑之前并抢先加载新类。

    dex级别的类插桩方案:重新排列旧包和补丁包中的dex文件的顺序,进行重组,使系统自然识别这个顺序,实现类的覆盖。

    part 2. 资源修复

    大部分热修复框架的资源修复都或多或少参考了Instant Run

    Instant Run :是android studio2.0新增的一个运行机制,在你编码开发、测试或debug的时候,它都能显著减少你对当前应用的构建和部署的时间。

    特点:

    • 只对代码改变部分做构建和部署
    • 不重新安装应用
    • 不重启应用
    • 不重启activity

    所以我们平时运行项目时第一次编译会特别慢,之后稍有改动,再次运行就快很多了。

    原理:

    1. 构造一个新的AssetManager
    2. 通过反射调用addAssetPath把完整的新资源包加到AssetManager。这样就得到了一个含有完整新资源的AssetManager。
    3. 找到之前所有引用AssetManager的地方,并通过反射,把引用处换成新的AssetManager。

    Sophix的方案:直接替换现有的AssetManager所引用的资源包,这样就不需要重新创建一个AssetManager了。补丁包的package的id是0x66,与原来的资源包id(0x7f)不会发生冲突。

    特点:

    1. 不修改AssetManager的引用处,替换更加完整,安全。
    2. 不必下载完整包,补丁包中只含变动的资源。
    3. 不需要在运行时合成完整的包,不占用运行时计算和内存。

    part 3. so库修复
    so库的修复本质上是对native方法的修复和替换。

    采用类修复,通过反射注入的方式,将补丁so库的路径插入到NativeLibraryDirectory数组的最前面。这样在加载so库时,就能加载到补丁so库了,从而达到修复的目的。

    相关文章

      网友评论

          本文标题:Android热修复系列(一):认识篇

          本文链接:https://www.haomeiwen.com/subject/wglouqtx.html