Sophix及热修复原理介绍

Sophix相关书籍

深入探索Android热修复技术原理这本书主要讲解了Android的热修复中的热部署,冷部署以及资源和so库的修复技巧。全文主要讲Sophix应对以上四个方面的技术解析,不管是自家产品还是业界其他方案的横纵对比,Sophix技术目前都是最优的。

  1. 补丁小,合成不占太多空间和性能。
  2. 对代码的侵入小,对native代码的hook也精简,做到最大兼容。
  3. 支持的修复范围广。支持小范围的即时生效和大范围的冷启动。也支持so库和资源修复。

Hook技术

在事件分发流中,通过Hook钩子在事件传送到终点前截获并监控事件的传输,从而处理一些特定干预事件。

  • Java API Hook
    通过对Android平台的虚拟机注入与Java反射的方式,来改变Android虚拟机调用函数的方式(ClassLoader),从而达到Java函数重定向的目的。参考

Sophix不同之处

Sophix同时使用了热启动的底层替换方案及冷启动的类加载方案,两个方案使用的补丁是相同的。优先热启动。

Sophix及热修复原理介绍_第1张图片
sophix与主流框架对比

代码修复方案

底层替换方案
  • 原理:在已经加载的类中直接替换掉原有方法,是在原有类的结构基础上进行修改的。在hook方法入口ArtMethod时,通过构造一个新的ArtMethod实现替换方法入口的跳转。
  • 应用:能即时生效,Andfix采用此方案。
  • 缺点:底层替换稳定性不好,适用范围存在限制,通过改造代码绕过限制既不优雅也不方便,并且还没提供资源及so的修复。
类加载方案
  • 原理:让app重新启动后让ClassLoader去加载新的类。如果不重启,原来的类还在虚拟机中无法重复加载。

  • 优点:修复范围广,限制少。

  • 应用:腾讯系包括QQ空间,手QFix,Tinker采用此方案。
    QQ空间会侵入打包流程。
    QFix需要获取底层虚拟机的函数,不稳定。
    Tinker是完整的全量dex加载。

dex的大小占整个apk比例较低,一个app里的dex文件大小不是主要部分,占空间大的主要是资源文件。

Sophix及热修复原理介绍_第2张图片
冷启动主流框架分析
  • QQ空间的插桩原理
    将一个单独无关版主类放到一个单独的dex中,原dex中所有类的构造函数都引用这个类,一般的实现方法都是侵入dex打包流程,利用.class字节码修改技术,在所有.class文件的构造函数中引用这个帮助类。

  • Tinker与Sophix方案不同之处
    Tinker采用dex merge生成全量DEX方案。反编译为smali,然后新apk跟基线apk进行差异对比,最后得到补丁包。
    Dalvik下Sophix和Tinker相同,在Art下,Sophix不需要做dex merge,因为Art下本质上虚拟机已经支持多dex的加载,要做的仅仅是把补丁dex作为主dex(classes.dex)加载而已:
    将补丁dex命名为classes.dex,原apk中的dex依次命名为classes(2, 3, 4...).dex就好了,然后一起打包为一个压缩文件。然后DexFile.loadDex得到DexFile对象,最后把该DexFile对象整个替换旧的dexElements数组就好了。


    Sophix及热修复原理介绍_第3张图片
    Tinker与Sophix方案不同点

DexFile.loadDex流程
DexFile.loadDex尝试把一个dex文件解析并加载到native内存,在加载到native内存之前,如果dex不存在对应的odex,那么Dalvik下会执行dexopt,Art下会执行dexoat,最后得到的都是一个优化后的odex。实际上最后虚拟机上执行的是这个odex而不是dex。


Sophix及热修复原理介绍_第4张图片
dexopt流程

资源修复方案

基本参考InstantRun的实现:构造一个包含所有新资源的新的AssetManager。并在所有之前引用到原来的AssetManager通过反射替换掉。
Sophix不修改AssetManager的引用,构造的补丁包中只包含有新增或有修改变动的资源,在原AssetManager中addAssetPath这个包就可以了。资源包不需要在运行时合成完整包。

so库修复方案

本质是对native方法的修复和替换。类似类修复反射注入方式,将补丁so库的路径插入到nativeLibraryDirectories数据最前面。

热修复主流框架对比可查阅
Android热修复主流框架调研

你可能感兴趣的:(Sophix及热修复原理介绍)