做android开发的,或多或少都应该听说过方法数65535的限制,我这原先没注意过,一直认为写的几个小程序不太可能超过, 最新尝试Rx, 把RxJava,RxAndroid,RxBinding一系列包导入后,AS就不干活了,一度害的我找了半天原因,还以为导入的出问题了,最后才发现是这个原因,顺便找了下解决办法, 记录下
About the 64K Reference Limit
产生的原因,按照文档的说法是, 在 android的app中,所有的代码,都会被打包成一个Dex文件,用于给Dalvik虚拟机执行, 而Dalvik设计时,限制了单个Dex文件 最多包含65535个方法(包含framework,library的方法); 而65535=64*1024, 就被叫做"64K reference limit"
查了下具体原因, 好像是 在android启动app时,有一步对Dex优化, 这个过程有个叫 DexOpt的工具来实现, DexOpt在第一次加载Dex时执行,会生成一个ODEX文件, 即Optimised Dex; ODEX的效率会比直接执行Dex的效率高很多, 但是DexOpt有一个问题, DexOpt会把所有类的方法id进行检索,存在一个链表中间, 而链表的长度是用short类型表示, 从而导致方法id的数目不能超过65535;
而android给出的解决办法就是,生成多个dex文件
解决办法
在api 21中, 提供了一个官方的解决办法 multidex support library
集成方法也很简单,就两步
- 修改gradle配置, 导入mutidex的依赖, 并且允许mutildex
- 如果工程又Application类, 将Application改为继承android.support.multidex.MultiDexApplication类, 如果Application类无法改或者不想该继承, 则可以重写attachBaseContext(),并调用下MultiDex.install(this)
gradle配置
android {
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 21
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
application
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
[参考]
https://developer.android.com/studio/build/multidex.html
http://blog.csdn.net/t12x3456/article/details/40837287