1.问题显示:
旧版编译时出现:
Conversion to Dalvik format failed:
Unable to execute dex:method ID not in [0,0xffffff]:65536
新版编译出现:
trouble writing output:
Too many field references :xxxx;max is 65536
2.原因:
android Dalvik 执行的由class编译后的.dex文件文件规定了单个.dex 文件最多能引用65536个方法,此问题描述为64K(65536/1024),或者65K(65536/1000),导致的编译错误提示
3.处理方式:
1. 尽量避免,遏制在摇篮中(毕竟分包是会影响性能的)
dex文件的来字所有的class文件,包含自身的方法,还有系统自带的方法和第三方开源库,尽可能的去减少不用的函数,不要为了小功能而引入大框架,小功能可以自己去实现,或者在开源库中提取需要的方法,这也是我们需要解读开源的一方面,提取所需,避免大炮打苍蝇,方法尽量复用
2.使用Progurad 混淆来去掉无用的代码,在Release版本中是能ProGuard
3.分包处理
当项目过大无可避免的时候,只能做手术了,把dex文件分成多个包来处理,每个包小于64方法
通过使用系统自带的MulitDex来分包使能分包方式,
1.首先引入它的库和其他第三方库一样添加
compile 'com.android.support:multidex:1.0.1'
2. 使能 multidex 的支持
defaultConfig{
minSdkVersion 18
targetSdkVersion 23
.........
//使能 multidex 的支持
multiDexEnabled true
}
3.在Application中的attachBaseContext方法中方法中初始
如果没有定义Application,则定义一个继承MultiDexApplicaon的类,重写onCreate,调用下父类的该方法即可
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this)
}
最后注意:
添加了分包处理可能出现的问题:
1.因为多个dex,安装可能导致ANR
2.4.0之前的版本可能出现启动失败(不过现在该系统使用的比例很小了)
3.大额的内存申请分配时可能出现crash,因为加载堆内存的大小被系统写死了,android 2.3 以下3M,2.3 5M,4.0 16,5.0由于是ART虚拟机不考虑该问题
4.分包后出现,主从dex文件包(一个主dex,1个或多个从dex),应用启动所需要的类必须放在主dex包中不然会出现NoClassDefFoundError错误,虽然大多时候,不需要关系,系统会自动帮我们把需要的类添加到主dex包中,但是对于第三依赖库需要还需要依赖其他的库的话,比如反射用的类,或者NDK代码用的类,如果在启动就需要用到那么就需要放到主包中
5.编译构建打包时因为要计算方法,分包处理等,所以很慢,
处理方式
调试时在构建时选择5.0以上系统构建,因为该系统是ART虚拟机,直接生成一个oat文件,而不是多个dex合并加载,发布版时 改为支持的最低版本
android{
productFlavors{
dev{
minSdkVersion 21
}
prod{
minSdkVersion 14//app实际的minSdkVersion
}
}
}