Android:一个Multidex引发的VerifyError和Class Not Found问题
来源:互联网 发布:双色球红球246计算法 编辑:程序博客网 时间:2024/06/16 12:49
一个困扰两天的问题终于解决了,下面记录一下该问题解决的历程,希望能对那些遇到类似问题的猿们有些帮助。
问题背景
由于项目要适配android4.X,而应用需要引用的一个jar包的4.X版本就只能用JDK1.6来编译,而应用要用JDK1.7来编译,这个情况也为该问题的解决带来了干扰。
当把编译好的jar包放入应用中,且应用编译通过,运行时报各种问题:
java.lang.VerifyErrorjava.lang.NoClassDefFoundError
等等……
网上说的各种解决办法都试过了也没用。后来看到一个帖子
http://www.cnblogs.com/successjerry/p/4402962.html
说java.lang.VerifyError的解决办法,说是proguard引起的。但是我编译的是debug版本,根本没有用proguard啊!但实在没办法了,我就想编个release版本看看我的proguard有没有问题。结果一试上面的两个报错都没有了,但是出现 了另外一个class找不到的现象,是一个匿名内部类找不到。
其实这个时候应该可以想到的是可能是proguard去除了无用的方法,导致应用的方法数在65535之内,前面的出问题的几个类回到了主包,因此前面出现的两个问题就没有了。
但是但是只考虑是progurad混淆引起的,通过反编译apk也确实发现匿名内部类创建是变成了new 1(this)之类的,但是主要解决方向都在这里。
后来纠结了两天,当中也请教了好多人,还是没有解决。当时想着就先放一放,就把这个出错的地方注释掉了,应用可以跑起来了。
后来的一个线索的出现是,当时修改了一下jar包,往里面添加了几个方法,运行应用的时候又出现类找不到,方法找不到,这是就恍然大悟了,可能是方法超限的问题导致的。
后来看了一下应用的设置,在build.gradle里面确实配置了分包:
multiDexEnabled true
解决办法
后来在网上查资料,发现
http://blog.csdn.net/t12x3456/article/details/40837287
可能需要在Application类的attachBaseContext方法中加上:
android.support.multidex.MultiDex.install(this);
一试,果然没有报错了。
在
http://weibo.com/p/1001603884849646685222
和
http://blog.csdn.net/qq2603825424/article/details/48311961
中有介绍:
使用了Multidex的APK运行在Android5.0之前的设备上时,还需要配合support库里面的MultiDex.install接口才行。有三种方法使用MultiDex.install接口:
- 如果没有自定义自己的Application,那么在AndroidManifest.xml将APK的Application指定为MultiDexApplication。
- 如果自定义了自己的Application,那么将自己的Application继承于MultiDexApplication。
- 如果不想继承于MultiDexApplication,那么重写父类Applicatio的成员函数attachBaseContext,并且在该成员函数中调用MultiDex.install接口。
这里我们采用方法3。
最后,使用了Multidex的APK运行在Android5.0之后的设备上时,不需要MultiDex.install支持。这是因为Android 5.0使用的是ART虚拟机,ART虚拟机解决了Dalvik虚拟机方法数限制在65K的问题。Android 5.0在安装一个使用了MultiDex的APK时,会收集它的Main Dex和Additional Dex,然后将它们翻译成Native Code,最终保存在一个OAT文件中。因此就不需要MultiDex.install了。
MultiDex.install干了什么事情呢?它首先是收集APK里面的Additional Dex,并且找到APK所使用的PathClassLoader。接下来通过反射得到PathClassLoader的成员变量pathList,这是一个类型为DexPathList的对象。DexPathList里面又有一个成员变量dexElements,指向的是一个Element数组,该数组包含了系统主动为APK加载的Dex。再接下来,又通过反射调用上述的DexPathList对象的成员函数makeDexElements加载前面找到的Additional Dex,并且将这些Additional Dex增加到它的成员变量dexElements描述的Element数组中。
Dalvik虚拟机在查找一个Class的时候,会询问APK使用的PathClassLoader。PathClassLoader又询问它的成员变量pathList指向的DexPathList对象。DexPathList又询问保存在它的成员变量dexElements描述的一个Element数组中的Dex。因此,就可以想象中,一旦MultiDex.install调用过后,APK就可以正常使用打包在AdditionalDex中的Class。
总结
其实在当发生Debug报错而Release版本有些报错就没有的时候,本来就可以往这方法考虑的,但是当时走错了方向,一直以为是混淆导致的问题,没有考虑到minifyEnabled true这个配置在release中也生效了。
希望对大家有所帮助。
- Android:一个Multidex引发的VerifyError和Class Not Found问题
- export引发的血案,ldd not found问题分析
- 关于Android MultiDex的问题
- Android Multidex 遇到的问题
- Android Activity Class Not found
- 解决 Android 在Eclipse 开发中 Class Not Found 的问题
- unity3d android打包中的class , .layout not found 等的问题研究
- SSH中spring和struts2整合遇到的问题,Action class not found
- 配置struts2遇到的class not found 的问题
- android:一个Open键引发的问题!!
- MultiDex使用中导致的crash(VerifyError)问题解决方案
- php Class ‘mysqli’ not found 问题
- php Class ‘mysqli’ not found 问题
- 山寨QQ问题:class not found
- Web Application 中的Class not found 问题
- php Class ‘mysqli’ not found 问题
- "Class not found: javac1.8"问题总结
- laravel 问题 Class 'Predis\Client' not found
- 小感慨
- eclipse安装svn
- OpenCV中特征点提取和匹配的通用方法
- pdf2htmlEX 安装与保持最新版本
- js转换时间戳
- Android:一个Multidex引发的VerifyError和Class Not Found问题
- java Collection概述
- NSCalendar + NSDateComponents
- CMake如何查找链接库,路径错误
- soundtouch 变声使用和算法
- codevs 1069 关押罪犯 并查集
- 一元云购系统接入手机短信功能说明【V3版】
- Ubuntu搭建LAMP环境
- HTTP协议