5.9 热修复技术

  热修复是在应用的App包发布到市场之后,出现了Bug,无需替换包来进行在线更新的一种技术,对用户是无感知的。目前广义上有两种方案可以实现代码的替换,一种是类的替换,基于Classloader;另一种是方法的替换,而这两种方式各有优缺点。

  1. 方法的替换:只能替换方法的内容,所以不能够对要patch的类进行方法的新增和删除;但同时,方法的替换可以在应用不重启的情况下实现。它包小、快速、功能单一、比较轻量,这种方案是热修复
  2. 类的替换:可以修改类结构,功能更加的强大;但是必须要重启一次才会有效,因为已经加载过的类是不能够被替换的。这种方案叫做“动态部署”。它几乎能够适应任何代码的变更,所以很适合进行业务功能的迭代。
  • 方法的替换

  如图所示,方法的替换的原理如下:在Android底层,有个数据结构记录着类的信息,比如成员变量的个数,方法的个数,每个方法的code执行地址,程序运行的时候会根据这个地址跳转到具体的code区域执行代码。方法的替换就是替换这些地址,把地址指向另一个类的方法,从而达到了替换的目的。这种方式的包比较小,而且也不需要插桩来影响性能,但是它无法修改类的结构(比如方法数的增删),而且有可能会有兼容性问题,例如厂商修改了类和方法的底层结构。

Andfix

  Andfix是阿里巴巴开源项目。AndFix就是 “Android Hot-Fix”的缩写,一个Android App的在线热补丁框架。使用此框架,我们能够在不重复发版的情况下,在线修改App中的Bug。就目前来说,AndFix支持Android 2.3到6.0版本,并且支持arm 与 X86系统架构的设备。完美支持Dalvik与ART的Runtime。

  AndFix 的补丁文件是以.apatch结尾的文件。Andfix的修复是方法级的,对有bug的方法进行替换。

  使用这个框架的局限在于不能修改全局变量,不能加新的方法,不过可以在现有的方法上做修改,加局部变量。从这方面来看,Andfix其实要求我们只是修改方法里面的bug,不能大规模做更改。如果我们觉得这种修复不能满足修复要求,那么,可以看另外这种,局限更少的热修方案。

实现方法如下:

1. 在自定义Application中初始化,为了更早的修复应用中的bug。

package com.euler.andfix;
import android.app.Application;
import com.alipay.euler.andfix.patch.PatchManager;
public class MainApplication extends Application {
    public PatchManager mPatchManager;
    @Override
    public void onCreate() {
        super.onCreate();
        mPatchManager = new PatchManager(this); // 初始化patch管理类
        mPatchManager.init("1.0"); // 初始化patch版本
        mPatchManager.loadPatch();// 加载已经添加到PatchManager中的patch
    }
}

2. 如果有新的补丁需要修复,下载完成后,进行以下操作

mPatchManager.addPatch(path); //添加patch,只需指定patch的路径即可,补丁会立即生效

3. 当apk版本升级,需要把之前patch文件的删除,需要以下操作

mPatchManager.removeAllPatch();

4. patch文件的生成

使用工具:apkpatch-1.0.3

原理:根据两个apk包,生成一个差异文件,就是所谓的补丁文件即patch文件。

命令 : apkpatch.bat -f new.apk -t old.apk -o output1 -k debug.keystore -p android -a androiddebugkey -e android
-f <new.apk> :    新版本
-t <old.apk> :     旧版本
-o <output> :      输出目录
-k <keystore>:     打包所用的keystore
-p <password>:     keystore的密码
-a <alias>:         keystore 用户别名
-e <alias password>: keystore 用户别名密码

执行完命令,就会在输出目录中输出.apatch文件:

  • .apatch文件中包含META-INF和classes.dex两个文件;
  • META_INF中有CERT.RSA,CERT.SF,MANIFEST.MF和PATCH.MF;
  • PATCH.MF的内容如右图所示

  注:Patch-Classes就是改动过的class。

5. 客户端请求服务器接口(api),服务器根据用户传递的数据分析是否有需要修复的bug。 如果有bug需要修复,就下载服务器指定的.apatch文件的链接,下载完后及时加载并修复,使用addpatch(path)方法,补丁会立即生效。

  • 类的替换(如HotFix项目)

  如图所示,APK包中包含了代码和资源,代码存放在classes.dex中,资源存放在APK的res目录下,系统会通过ClassLoader装载classes.dex来进行类加载。如果有多个classes.dex,那么这多个classes.dex会在ClassLoader中会用数组的形式来进行组织,然后从前往后进行遍历查找。

  一种具体的方案如图2所示,是利用多dex从前往后遍历的有序特性,把patch.dex插入到数组的最前面,对patch进行有限查找,达到替换的目的,这时候就会出现preverify问题,为了绕过这个问题,就必须往每个类的构造函数里面进行插桩防止安装期间的校验,把校验从编译期间移动到了运行期间,导致运行期间每加载一个类,都要进行校验和优化,降低了运行性能。

  这种方案利用了ClassLoader,思想是比较好的,但是如果工程中的类比较多,就会在性能上造成比较大的影响。同时,有可能会导致patch包比较大。

  为了解决上述性能问题,出现了另一种方案,如图3所示:就是全量替换dex,下发一个patch.dex,然后把原来的dex和下发的patch.dex,合成一个新的全量dex,这个dex会全量替换原来的dex,最终本质上也只会在这个全量的dex中查找,从而不会出现preverify问题,所以这种方案不用插入构造函数,不会影响性能。但是,这种方案的包也可能会比较大,只改动了一行代码,也必须合成一个全量的dex,如图4所示,然后再dexopt出一个全量的odex。

Hotfix

  该项目是基于QQ空间终端开发团队的技术文章实现的。项目包括核心类库,补丁制作库,例子。该技术的原理是用ClassLoader加载机制,覆盖掉有问题的方法。所以我们的补丁其实就是有问题的类打成的一个包。

如何选择热修复技术方案

  • 热修复技术方案的选择应该对应具体的使用场景。
  • 在patch包的数量、大小方面,热修复(Andfix是占优势的;
  • 但是热修复(Andfix不能新增类、新增字段,从这个角度看,ClassLoader更好,但是会有一定的性能损耗;

合成dex的方式,则需要知道用户手机的ROM有多大,能不能提供20多M的空间来。

  对比两种解决方案,阿里的andfix更注重于改细节的bug,虽然它是从native层做得操作,但是框架封装的很好,我们使用起来很简便,而且有更新维护,据说阿里系的app打算都用这个。如果我们仅仅就是开发一款app,还没有大改动,不会热更全局变量,不会增加方法,那么这个框架就是首选。

  但是有的时候我们可能开发的是一款sdk,譬如友盟sdk之类,或者想热更全局变量,增加方法,那么andfix可以说是用不到的,所以这个时候hotfix是更好的选择。

时间: 2024-12-12 17:12:30

5.9 热修复技术的相关文章

Android热修复技术选型

2015年以来,Android开发领域里对热修复技术的讨论和分享越来越多,同时也出现了一些不同的解决方案,如QQ空间补丁方案.阿里AndFix以及微信Tinker,它们在原理各有不同,适用场景各异,到底采用哪种方案,是开发者比较头疼的问题.本文希望通过介绍QQ空间补丁.Tinker以及基于AndFix的阿里百川HotFix技术的原理分析和横向比较,帮助开发者更深入了解热修复方案. 技术背景 一.正常开发流程 从流程来看,传统的开发流程存在很多弊端: 重新发布版本代价太大 用户下载安装成本太高 B

Android 热修复技术(1)---原理

热修复技术分为几部分: 原理介绍 Android HotFix源码分析 自定义框架 1.Android分包MultiDex原理 首先Dex是什么东西? Dex就是Window里面的exe文件 也就是可执行问题. Android没有用传统的Java虚拟机,而是使用dalvik虚拟机.当APK安装到手机后,dalvik会先把de文件转化位ODEX文件, 优化结构. 在早期的android系统中,为了优化dex,所有的method会存放在一张表里面,表的大小位short,也就是65535(65K) B

全面了解Android热修复技术

WeTest 导读 本文探讨了Android热修复技术的发展脉络,现状及其未来. 热修复技术概述 热修复技术在近年来飞速发展,尤其是在InstantRun方案推出之后,各种热修复技术竞相涌现.国内大部分成熟的主流APP都拥有自己的热修复技术,像手淘.支付宝.QQ.饿了么.美团等等. 目前能搜集到的资料,大多简单罗列每个方案的特点并进行横向比较,而其中技术发展的脉络往往被掩盖了.热修复技术从何而来,又将往何处去?在这些资料中都找不到答案. 我认为,走马观花地看一遍各家的热修复方案并不能找到答案,所

Android热修复技术选型——三大流派解析

2015年以来,Android开发领域里对热修复技术的讨论和分享越来越多,同时也出现了一些不同的解决方案,如QQ空间补丁方案.阿里AndFix以及微信Tinker,它们在原理各有不同,适用场景各异,到底采用哪种方案,是开发者比较头疼的问题.本文希望通过介绍QQ空间补丁.Tinker以及基于AndFix的阿里百川HotFix技术的原理分析和横向比较,帮助开发者更深入了解热修复方案. 技术背景 -----------------------------------------------------

Android热修复技术专题:来自微信、淘宝、支付宝、QQ空间的热修复方案

最近好多人都讨论关于热更新的话题,所以查询了一些资料看看 当一个App发布之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包App.测试.向各个应用市场和渠道换包.提示用户升级.用户下载.覆盖安装.有时候仅仅是为了修改了一行代码,也要付出巨大的成本进行换包和重新发布. 这时候就提出一个问题:有没有办法以补丁的方式动态修复紧急Bug,不再需要重新发布App,不再需要用户重新下载,覆盖安装?答案当然是有的,那就是最近涌现出来得热补丁方案,主要包括淘宝的Dexpo

Android Classloader热修复技术之百家齐放

大概在2015年10月底,QQ空间发了一篇叫<安卓App热补丁动态修复技术介绍>的文章,文章中提到为了能让Class进行热修复,其中一个条件就是防止类被打上CLASS_ISPREVERIFIED标记,具体的做法便是让一个Dex引用另一个Dex(hack.apk)中的空类(为了让业务无感知,需要在编译时动态注入字节码),并且在应用程序Application类起来的时候要加载这个hack.apk.也就是说最多需要进行两次反射,即加载hack.apk的时候需要进行一次反射操作,将hack.apk加入

Android Gradle项目Hotfix热修复技术的接入

https://github.com/AItsuki/HotFix Issues MAC系统无法自动打包补丁,原因可能是路径分隔符问题 使用谷歌multidex分包后无法注入代码(开启multidex之后,jar包保存路径改变了) 暂不支持productFlavors 以上问题有空再改,最近正在忙其他事情,公司项目也准备重构. 而且此项目主要是科普和学习热补丁技术,有兴趣的可以自行解决上述问题. 一.HotFix简介 一个基于dex分包的热补丁框架,目前只支持gradle 1.5以上版本 具有以

线上热修复技术

没学会.没接触的时候感觉很难,学会了也就没那么难 1.前言 2.相关技术 阿里巴巴  AndFix.Dexposed QQ空间  超级补丁  微信  Tinker (一)AndFix与hotFix技术 AndFix不同于QQ空间超级补丁技术和微信Tinker通过增加或替换整个DEX的方案,提供了一种运行时在Native修改Filed指针的方式,实现方法的替换,达到即时生效无需重启,对应用无性能消耗的目的. (二) 超级补丁 超级补丁技术基于DEX分包方案,使用了多DEX加载的原理,大致的过程就是

Android热修复技术

更新版本一直以来是移动端的一大痛点,各大公司也推出了相应的解决方案. 1)AndFix(阿里巴巴):兼容性不太好,亲试过,上线反馈崩溃问题特别严重. 2)Tinker(微信):集成起来是相当的麻烦 看完http://blog.csdn.net/u010983881/article/details/53196574这个链接,基本就能接入了. 但是还有一些需要补充的  1>Android的一些编译打包命令:http://blog.csdn.net/dakaring/article/details/4