美文网首页
Android热修复浅析

Android热修复浅析

作者: 灬丨墨殇丶 | 来源:发表于2015-12-31 13:59 被阅读0次

背景

当一个App发布之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包App、测试、向各个应用市场和渠道换包、提示用户升级、用户下载、覆盖安装。有时候仅仅是为了修改了一行代码,也要付出巨大的成本进行换包和重新发布。

这时候就提出一个问题:有没有办法以补丁的方式动态修复紧急Bug,不再需要重新发布App,不再需要用户重新下载,覆盖安装?

答案是:可以的

解决方案

1、Xposed

先来了解一下Xposed:诞生于XDA论坛,类似一个应用平台,不同的是其提供诸多系统级的应用。可实现许多神奇的功能。Xposed需要以越狱为前提,也就是说需要root权限,想了解详细,可以自行查阅相关资料,由于需要root权限,但我们的APP对于用户的手机来说,不太可能人人都root,用户也不会自行去安装这个工具,所以此方案对我们APP来说不合适。

2、Dexposed

DexPosed是强大而无侵入的AOP(面向切面编程)运行Android应用程序开发框架,基于开源的Xposed框架项目的工作(Xposed是修改系统框架服务的框架),拥有强大的:「原方法前hook」「方法替换」「原方法后hook」三种方式。相互组合,可依据你的hook思想,解决和规避几乎所有的意外情形。它更像是一个hook工具,效果跟使用者思路关系紧密,是地地道道的hook方案。在阿里有着良好的实践成果。

此方案的确可以解决BUG的热修复问题,但有很大的弊端,就是系统兼容性问题:

支持的系统

也就是说对于Android5.0系统之后,我们的热修复还是失败的,那么有木有一种方案是,不需要root,而且平台范围支持广的方案呢?那就是我们今天要重点说的AndFix方案了。

3、AndFix

AndFix,全称是Android hot-fix。是阿里开源的一个热补丁框架,允许APP在不重新发布版本的情况下修复线上的bug。支持Android 2.3 到 6.0,并且支持arm 与 X86系统架构的设备。完美支持Dalvik与ART的Runtime,补丁文件是以 .apatch 结尾的文件。

AndFix原理

AndFix的原理就是方法的替换,把有bug的方法替换成补丁文件中的方法。

注:在Native层使用指针替换的方式替换bug方法,已达到修复bug的目的。


使用AndFix修复热修复的整体流程:


方法替换过程:

Android上如何使用

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

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

//添加patch,只需指定patch的路径即可,补丁会立即生效

mPatchManager.addPatch(path);

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

mPatchManager.removeAllPatch();

使用工具:apkpatch-1.0.3

它根据两个apk差别来生成apatch文件,不要将其完全理解成是一个差异文件。它是对比两个apk中的smali文件,找到不同的方法,增加方法annotation(供客户端修复逻辑识别并修复),保留此方法所在类的smali描述,修改类名、将其再打成dex,并与META-INF下的签名、证书、包含有patch信息的PATCH.MF一并打成一个压缩文件,文件格式命为apatch。

对smali类方法修改的内容如下:

.class public Lcom/open/andfixdemo/MainActivity_CF;

.super Landroid/app/Activity;

.source "MainActivity.java"

.method public showResultAsTextView()V

.locals 2

.annotation runtime Lcom/alipay/euler/andfix/annotation/MethodReplace;

clazz = "com.open.andfixdemo.MainActivity"

method = "showResultAsTextView"

.end annotation

.prologue

.line 42

const v1, 0x7f080002

invoke-virtual {p0, v1}, Lcom/open/andfixdemo/MainActivity_CF;->findViewById(I)Landroid/view/View;

move-result-object v0

check-cast v0, Landroid/widget/TextView;

.line 43

.local v0, "textView":Landroid/widget/TextView;

const-string v1, "4"

invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V

.line 44

return-void

.end method

.method public showResultAsToast()V

.locals 2

.annotation runtime Lcom/alipay/euler/andfix/annotation/MethodReplace;

clazz = "com.open.andfixdemo.MainActivity"

method = "showResultAsToast"

.end annotation

.prologue

.line 38

const-string v0, "2"

const/4 v1, 0x1

invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

move-result-object v0

invoke-virtual {v0}, Landroid/widget/Toast;->show()V

.line 39

return-void

.end method

请留意这些修改:

类名由MainActivity被修改成为MainActivity_CF。

被替换的方法showResultAsTextView、showResultAsToast被添加了一个MethodReplace注解。注解描述中说明了原类及原方法。

由此,你应该了解到,对于客户端,这些信息已经足够。那么客户端的处理为:解析apatch->解析dex->加载类->识别含有MethodReplace注解的方法->根据原方法签名已经新方法smali描述进行hook并替换。

命令:

apkpatch.bat-f new.apk-t old.apk-o output-k debug.keystore-p android-a androiddebugkey-e android

-f:新版本

-t: 旧版本

-o: 输出目录

-k: 打包所用的keystore

-p: keystore的密码

-a: keystore 用户别名

-e: keystore 用户别名密码

注:debug.keystore我用的是.android目录下默认签名工具,需要先把debug.keystore拷到apkpatch-1.0.3根目录下

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

.apatch文件根目录内容:

META_INF文件下内容:

PATCH.MF文件内容:

diff.dex文件反编译后的结果:

在Android Studio使用

gradle dependency:

dependencies{

     compile 'com.alipay.euler:andfix:0.3.1@aar'

}

在Eclipse使用

把Java层的代码引入到你的工程,配置Ndk开发环境并把jni Native代码添加进来。

代码混淆(ProGuard)

-keep class *extendsjava.lang.annotation.Annotation

-keep classeswithmembernamesclass* {

    native <methods>;

}

其他方案

DexPosed和AndFix都属于修改Java类的C层对象来实现实现热修复,QQ空间的nuwa方案是通过修改BaseDexClassLoader中的pathList,来动态加载dex方式实现热修复。后者纯java实现,但需要hack类的优化流程,将打CLASS_ISPREVERIFIED标签的类,去除此标签,以解决类与类引用不在一个dex中的异常问题。这会放弃dex optimize对启动运行速度的优化。原则上,这对于方法数没有大到需要multidex的应用,损失更明显。

问题:

1、线上分次发布多patch

2、拿不到签名工具

参考资料:

1、alibaba/AndFix · GitHub

2、alibaba/dexposed · GitHub

3、【新技能get】让App像Web一样发布新版本

4、Alibaba-Dexposed框架在线热补丁修复的使用 - Coolspan - 博客频道 - CSDN.NET

5、Android-FixBug热修复框架的使用及源码分析(不发版修复bug) - Coolspan - 博客频道 - CSDN.NET

相关文章

网友评论

      本文标题:Android热修复浅析

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