标签:
随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误:
<span style="color:#ff0000;">UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536 at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501) at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:282) at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:490) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167) at com.android.dx.merge.DexMerger.merge(DexMerger.java:188) at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287) at com.android.dx.command.dexer.Main.run(Main.java:230) at com.android.dx.command.dexer.Main.main(Main.java:199) at com.android.dx.command.Main.main(Main.java:103) </span>
近日,Android Developers在Google+上宣布了新的Multidex支持库,为方法总数超过65K的Android应用提供了官方支持。
如果你是一名幸运的Android应用开发者,正在开发一个前景广阔的应用,不断地加入新功能、添加新的类库,那么终有一天,你会不幸遇到这个错误:
Conversion
to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
这个错误是Android应用的方法总数限制造成的。Android平台的Java虚拟机Dalvik在执行DEX格式的Java应用程序时,使用原生类型short来索引DEX文件中的方法。这意味着单个DEX文件可被引用的方法总数被限制为65536。通常APK包含一个classes.dex文件,因此Android应用的方法总数不能超过这个数量,这包括Android框架、类库和你自己开发的代码。
这个问题可以通过将一个DEX文件分拆成多个DEX文件解决。Facebook介绍了为Android应用开发的Dalvik补丁;Android Developers博客介绍了通过自定义类加载过程的方法来解决此问题。但这些方法有些复杂而且并不优雅。
随着新的MultiDex支持库发布,Google正式为解决此问题提供官方支持。构建超过65K方法数的应用介绍了如何使用Gradle构建多DEX应用。
首先使用Android SDK Manager升级到最新的Android SDK Build Tools和Android Support Library R21。然后进行以下两步操作:
1.修改Gradle配置文件,启用MultiDex并包含MultiDex支持:
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‘ }
2.让应用支持多DEX文件。在MultiDexApplication JavaDoc中描述了三种可选方法:
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); }
使用MutiDex的主意事项
一. 如果你继承了MutiDexApplication或者覆写了Application中的attachBaseContext()方法.
Application类中逻辑的注意事项:
Application 中的静态全局变量会比MutiDex的 instal()方法优先加载,所以建议避免在Application类中使用静态变量引用main classes.dex文件以外dex文件中的类,可以根据如下所示的方式进行修改:
二. 虽然Google解决了应用总方法数限制的问题,但并不意味着开发者可以任意扩大项目规模。Multidex仍有一些限制:
避免应用过大、方法过多仍然是Android开发者要注意的问题。Mihai Parparita的开源项目dex-method-counts可以用于统计APK中每个包的方法数量。
通常开发者自己的代码很难达到这样的方法数量限制,但随着第三方类库的加入,方法数就会迅速膨胀。因此选择合适的类库对Android开发者来说尤为重要。
开发者应该避免使用Google Guava这样的类库,它包含了13000多个方法。尽量使用专为移动应用设计的Lite/Android版本类库,或者使用小类库替换大类库,例如用Google-gson替换Jackson JSON。而对于Google Protocol Buffers这样的数据交换格式,其标准实现会自动生成大量的方法。采用Square Wire的实现则可以很好地解决此问题。
常见问题
对于dex 的--multi-dex 选项设置与预编译的library工程有冲突,因此如果你的应用中包含引用的lirary工程,需要将预编译设置为false:
使用eclipse的开发人员可以参考Google官方文档
https://developer.android.com/tools/building/multidex.html#mdex-gradle
需要安装支持gradle构建的插件,下载地址:
http://dist.springsource.com/release/TOOLS/gradle (目前可能需要翻墙)
1. MutiDex 官方文档: https://developer.android.com/reference/android/support/multidex/MultiDex.html
2. http://blog.osom.info/2014/10/multi-dex-to-rescue-from-infamous-65536.html
另附android -support-mutidex.jar下载地址: http://download.csdn.net/detail/t12x3456/8143383
补充注意事项:
如果遇到这个错误请进行如下检查:
1. 主工程与依赖library工程包名是否重复
2. 检查主工程与依赖library工程是否含有重复的support.jar或者其他jar包
解决方案:
1. 修改library工程包名
2. 删除重复jar包
3.手工添加lib包,增加如下配置
标签:
原文地址:http://blog.csdn.net/android_xiansheng/article/details/52441449