Android应用打破65K方法数限制
Posted Hi_XianSheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android应用打破65K方法数限制相关的知识,希望对你有一定的参考价值。
随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方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中描述了三种可选方法:
- 在AndroidManifest.xml的application中声明android.support.multidex.MultiDexApplication;
- 如果你已经有自己的Application类,让其继承MultiDexApplication;
- 如果你的Application类已经继承自其它类,你不想/能修改它,那么可以重写attachBaseContext()方法:
@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文件中的类,可以根据如下所示的方式进行修改: