Android 热补丁的一些总结

本文总结了Android热补丁的常见方案,如Dexposed、AndFix和Qzone,并探讨了其优缺点。热补丁能快速修复bug,适合灰度阶段验证修复效果和远端调试。此外,还介绍了温拔插和冷拔插的概念,以及InstantRun的工作原理。文章通过微信和QQ空间的热补丁方案对比,讨论了类加载冲突的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常见方案:淘宝的Dexposed、支付宝的AndFix以及Qzone

缺点:

补丁不能支持所有的修改,例如AndroidManifest;只能针对单一客户端版本,随着版本差异变大补丁体积也会增大

优点:

补丁大小均在300K

1天覆盖率达到70%以上;

修复bug

非常适合使用在灰度阶段(可以快速对同一批用户验证修复效果,若发布版本出现问题或紧急漏洞,传统方式需要单独灰度验证修改,然后重新发布新的版本。利用补丁技术,我们只需要先上线小部分用户验证修改的效果,最后再全量上线即可)。

远端调试

所以补丁机制非常适合使用在远端调试上。即我们需要具备只特定用户发送补丁的能力,这对我们查找问题非常有帮助。

A/BTest数据统计

例如若我想对同一批用户做两种test,传统方式无法让这批用户去安装两个版本。使用补丁技术,我们可以方便的对同一批用户更换补丁版本。

热拔插:代码改变被应用、投射到APP上,不需要重启应用,不需要重建当前activity。
场景:适用于多数的简单改变(包括一些方法实现的修改,或者变量值修改)
温拔插:activity需要被重启才能看到所需更改。
场景:典型的情况是代码修改涉及到了资源文件,即resources。

Tips:温拔插需要重启Activity,因为资源文件是在Activity创建时加载,所以必须重启Activity来重载资源文件。

冷拔插:app需要被重启(但是仍然不需要重新安装)

InstantRun

http://www.jianshu.com/p/2e23ba9ff14b

http://www.tuicool.com/articles/uQJjA3b


InstantRun原理:

运行Gradle任务来生成增量.dex文件(这个dex文件是对应着开发中的修改类) Android Studio会提取这些.dex文件发送到App Server。

在有Instant Run的环境下:一个新的App Server类会被注入到App中,与Bytecode instrumentation协同监控代码的变化。

同时会有一个新的Application类,它注入了一个自定义类加载器(Class Loader),同时该Application类会启动我们所需的新注入的App Server。于是,Manifest会被修改来确保我们的应用能使用这个新的Application类。(这里不必担心自己继承定义了Application类,Instant Run添加的这个新Application类会代理我们自定义的Application类)

这个自定义的classloader也要继承BaseDexClassLoader,因为BaseDexClassLoader里有个DexPathList,这个所谓的List里存的是多个dex的文件信息,所以当某段代码修改时,只需编译和替换相应的dex文件即可

源码中可以看到,Studio其实就是利用反射,将自己的IncrementalClassLoader设置成app中默认ClassLoader的parent,这样就拦截了所有类加载的动作,从而实现了对多个dex文件的动态加载。

可以参考:http://www.cnblogs.com/coding-way/p/5443718.html

经过实际测试:

android:name="com.android.tools.fd.runtime.BootstrapApplication"


方案对比:
微信:

根据BsDiff的改进算法DexDiff生成两个版本的差异dex,在用户手机上根据老dex还原出新dex。

问题:如何做到不刷新?

QQ空间

分包方案:就是把多个dex文件塞入到app的classloader之中,但是android dex拆包方案中的类是没有重复的,如果classes.dex和classes1.dex中有重复的类,当用到这个重复的类的时候,系统会选择哪个类进行加载呢?

理论上,如果在不同的dex中有相同的类存在,那么会优先选择排在前面的dex文件的类,如下图:


补丁的方案,把有问题的类打包到一个dexpatch.dex)中去,然后把这个dex插入到Elements的最前面。

但是会有问题,解决方法如下:

if (ClassVerifier.PREVENT_VERIFY) {

System.out.println(AntilazyLoad.class);

}

其中AntilazyLoad类会被打包成单独的hack.dex,这样当安装apk的时候,classes.dex内的类都会引用一个在不相同dex中的AntilazyLoad类,这样就防止了类被打上CLASS_ISPREVERIFIED的标志了,只要没被打上这个标志的类都可以进行打补丁操作。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值