本文参考自[安卓App热补丁动态修复技术介绍]


Android热修复实现:是基于dex分包方案,和Android虚拟机的类加载器ClassLodaer)实现的。
为什么会分包可参考:由Android 65K方法数限制引发的思考

当分包之后,会形成一个dex包的有序数组。当需要加载类文件时,ClassLoader会从数组中第一个dex包开始加载直至找到该类为止。
多个包中都包含相同类文件时,会取第一个类文件作为返回。如下图:两个dex包中都包含Qzone.class文件。

这里写图片描述

热修复是通过将已修复了bug的文件打成dex包(如:patch.dex),并将该补丁包放入dex分包的有序数组最前面当加载类文件时,此时的patch.dex中已修复的类文件取代了dex包相对靠后的原本存在bug的类文件从而实现了bug修复。如下图:

这里写图片描述

至于由于分包加载引起的 CLASS_ISPREVERIFIED 报错,是由于apk在安装的时候,虚拟机会对dex进行优化生成odex。其中如果A类引用了B类,同时A类和B类都在同一个dex包中,那么虚拟机给A类打上CLASS_ISPREVERIFIED 标记,可以算是一个深度优化的标记。假设现在B类中出现BUG,现在修复完成后将其放入patch.dex中,此时A和B就不在同一dex包中了,但类A始终有CLASS_ISPREVERIFIED 标记,所以在进行优化判断中发现两个类不在同一个dex包中,所以报错。

所以为了实现补丁方案,必须防止类被打上CLASS_ISPREVERIFIED 标志,而实现方式是在类的构造方法中加入一个不在该dex包中的类引用,以此避免实现该方案。


参考:

[安卓App热补丁动态修复技术介绍]

由Android 65K方法数限制引发的思考

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐