文本大纲文本CLASS_ISPREVERIFIED 兼容性问题
演示地址:https://github.com/18598925736/HotUpdateDemo/tree/4.4_crash_solution
问题描述
用一句话描述问题:
在apk安装过程中,如果Dalvik虚拟机发现某个类A引用的其他类与自身在同一个dex文件中,那么类A就会被打上CLASS_ISPREVERIFIED标记,以提高性能。那么按照这个思路,如果A类引用了一个有bug的类Util,那么我们就使用multidex热修复方案推送一个patch.dex给它,然后重新启动修复。这个类已经被标记了,但是重启app后,它引用的Util类此时和它不在同一个dex中(新的Util类在patch.dex中)。
这时,就发生了冲突。标记后,发现引用类不在dex中,程序会报错。
CLASS_ISPREVERIFIED分为4个字:class、is、pre-verified、该类是否预验证。
这个问题只会出现在Dalvik虚拟机下(4.4 sdk19以下默认使用dalvik,5.0 sdk 21之后默认使用art虚拟机)。艺术不会有类似的问题。因此,可以认为这个问题只出现在5.0以下(不含5.0)的机器上。
问题演示
我使用的是上一篇文章中Android Muitldex热更新修复方案原理的demo。
下载后直接在SDK 19 android4.4的模拟器上运行。
这是一个demo工程,添加了补丁包fix.dex。
直接运行时,你会发现程序崩溃,并出现以下错误:

一般的意思是对一个类的引用已经被预先验证了,但是没有找到预期的实现。这是因为被标记为CLASS_ISPREVERIFIED,然后打补丁修复,导致冲突。
解决方案
既然问题的根源在于引用Util的类A被标记为CLASS_ISPREVIRIFIED,那么有什么办法可以阻止这些类被标记呢?
思考:
问题:如何防止源代码中的所有类被标记为CLASS_ISPPREVERIFIED?
回答:
理论上,Android项目中的所有Java类(除了Application)都可能需要热修复。如果允许这些类引用另一个dex文件下的类,就可以防止它们在dex解析过程中被标记为CLASS_ISPPREVERIFIED。
但这样做有一个缺点,那就是CLASS_ISPPREVERIFIED带来的性能提升会消失。但既然出现了bug,解决它总是要付出代价的。价格我们稍后再说。
行动:
创建一个hack 模块,其中创建一个空白java 类AntilazyLoad。编译它,得到AntilazyLoad.class,然后使用dx命令将其打包成hack.dex。具体命令为: dx --dex --output=hack.dex ./com/zhou/hack/Antilazyload.class dx命令所在位置为如下图所示,注意添加到系统环境中变量路径:
2.使用gradle Instrumentation干扰gradle打包过程。在生成javac命令之后,dx命令之前,以及我们编写的所有类的构造函数内,添加直接使用AntilazyLoad(不允许反射引用)。
这句话信息量很大,请一步一步解释一下:
'''




















用户评论
终于找到解决AndroidMultidex热修复 CLASS_ISPREVERIFIED 问题的文章了!每次遇到这个坑都让我头疼,感谢作者分享这种实用技巧,太棒了!
有7位网友表示赞同!
我一直在纠结如何解决这堆类是否已验证的问题 ,看到这篇文章感觉好像找到了解药一样,马上试试看!
有13位网友表示赞同!
我公司最近换了一个热修复框架,结果出现了这个奇怪的错误。看了下代码,发现确实是使用MultiDex和热修复冲突了。看来该学习一下这篇文章的解决方案了。
有18位网友表示赞同!
写个应用程序的人可能不会遇到这个问题吧?因为我们不玩这些高级的东西,只是想让App正常工作就已经很高兴了!
有8位网友表示赞同!
文章介绍的方法听起来很专业,但我不太懂这些技术细节。希望能再详细一些,或者提供一些案例代码,这样对新手更友好。
有11位网友表示赞同!
热修复真的太棒了,可以大大减少版本迭代的麻烦。不过也确实经常能遇到各种各样的问题,比如这个 CLASS_ISPREVERIFIED 问题… 看这篇文章好像是个比较好的解决方法!
有12位网友表示赞同!
我平时开发都是用java编写的,对于热修复和MultiDex这种东西还没深入接触过。还是觉得原生开发更靠谱吧?
有15位网友表示赞同!
看来这个 CLASS_ISPREVERIFIED 问题确实很常见啊,到处都能找到解决方案。看来以后遇到这个问题就不用太担心了!
有8位网友表示赞同!
这篇文章的解决方法对我不太适用,因为我的项目使用的是其他类型的热修复框架。希望作者能针对不同的框架提供一些更具体的解决方案。
有15位网友表示赞同!
这个 CLASS_ISPREVERIFIED 问题一直困扰了我很久,今天终于看到了一种可以解决的方法!感觉很激动啊!
有8位网友表示赞同!
这篇文章写得真好,逻辑清晰,内容详尽。我之前一直没有明白 热修复的原理,看了这篇文章后恍然大悟!
有16位网友表示赞同!
Android 开发真太容易遇到各种问题了。这个 CLASS_ISPREVERIFIED 问题也不例外,看来我还有好多东西要学习。
有18位网友表示赞同!
我觉得代码注释可以再多一些,这样更容易理解每个步骤的操作。另外也可以添加一些错误处理和异常捕获的机制,更加完善一些。
有8位网友表示赞同!
热修复真的太棒了,可以让App的功能不断升级,而不用重新发布整个版本。这个 CLASS_ISPREVERIFIED 问题虽然烦人,但是也能让我学习到很多新的知识!
有9位网友表示赞同!
我试了这篇文章的方法,但是还是无法完全解决这个问题!难道我的代码还有其他问题吗?
有6位网友表示赞同!
希望作者能继续更新一些文章,分享更多 Android 开发的经验和技巧!我很期待!
有6位网友表示赞同!
文章虽然说的很详细,但对于没有热修复相关经验的人来说,理解起来还是有点困难… 希望有更直观的图文讲解!
有13位网友表示赞同!
AndroidMultidex 和热修复的结合确实是一项很有潜力的技术,可以提高App的运行效率和用户体验。期待看到更多优秀的实践案例。
有11位网友表示赞同!