Android 使用EventBus产生CLASS_ISPREVERIFIED引发的崩溃问题

最新项目中在整合EventBus的使用,在把EventBus整理之后,umeng上反馈了不少崩溃上来,产生log中错误信息都是一个:

Class ref in pre-verified class resolved to unexpected implementation

产生崩溃的类结构很简单:


Android 使用EventBus产生CLASS_ISPREVERIFIED引发的崩溃问题_第1张图片
产生异常的类

也就是项目中封装了一个Subscriber,当使用EventBus的时候都使用该对象的实例进行注册,发生问题都是在EventBus在对改对象注册的地方。

其实问题的发生点在于这个类被打上了CLASS_ISPREVERIFIED的标记而该类又引用不在一个dex中的EventBus,很久之前QQ空间发表过一篇文章论述热补丁的问题:

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

文章里详细说明了PRE_ISVERIFIED标记带来的问题,不想看文章的同学可以直接看下面:
我们知道class会被转化为dex文件以在android平台运行,dex文件在加载时又会转化成odex,而在这个过程中所有的类会做一个verify的过程,如果verify成功,那么这个class会被打上PRE_ISVERIFIED的标记,而这个类如果还去引用不同dex下的class,则会引发一开始的异常。
verify的过程是,检查类的 static方法、private方法、构造函数、override方法,如果这些方法里只有对同个dex下类的引用,那么就会被打上PRE_ISVERIFIED的标记。

那么一开头所说的问题原因是Subscriber类和EventBus分在了两个dex,Subscriber被打上了CLASS_ISPREVERIFIED的标记却又在非verify的方法中引用了EventBus。所以最后解决的方法是,在Subscriber类中的构造函数显示的引用了EventBus,这样这个类就不会被打上CLASS_ISPREVERIFIED的标记了:

Android 使用EventBus产生CLASS_ISPREVERIFIED引发的崩溃问题_第2张图片
image.png

在github上也有人问过这个问题了:
github

这个崩溃属于dex分包带来的问题,在项目过大的时候多多少少会遇到,而CLASS_ISPREVERIFIED标记也是为了提高加载性能,是否不打上该标记需要权衡项目大小而定。

你可能感兴趣的:(Android 使用EventBus产生CLASS_ISPREVERIFIED引发的崩溃问题)