DEX 方法超过64K限制和gradle编译OOM问题解决

enter image description here
若是你是一个android开发者,你至少据说过的Dalvik的蛋疼的64K方法限制。归纳地说,在一个DEX文件,你能够调用不少的方法,但你只能调用它们最前面的65,536个 ,由于这是在方法调用集合中的全部的空间了。若是你的源代码和狂拽炫酷叼炸天的三方库中方法超过了这个限制。看这篇文章就对了。 html

UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.Java:502) at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:277) at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:491) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:168) at com.android.dx.merge.DexMerger.merge(DexMerger.java:189) at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:302) at com.android.dx.command.dexer.Main.run(Main.java:245) at com.android.dx.command.dexer.Main.main(Main.java:214) at com.android.dx.command.Main.main(Main.java:106) java

点此查看更多相关话题 android

为了解决这个问题,Android开发社区有人想出了一些解决方案,好比dmarcato的这个,还有casidiablo的这个。他们都是可行的,可是须要一些比较严格的条件。 app

最终,Google决定提供一套官方的解决方案,在10月14日的时候发布了MultiDex 支持库,随后几周gradle在 v0.14.0版本中也支持了。 ide

使用MultiDex支持库

若是你在使用 Android Studio,这个用起来很简单。若是不是,强烈建议你迁移过来。由于Google很快就会不知处Eclipse插件和旧的基于Ant的系统构建方式。 测试

第1步 
添加依赖于你的build.gradle支持MultiDex库 gradle

dependencies { ... compile 'com.android.support:multidex:' ... } ui

第2步 
在buildType或productFlavor中开启multiDexEnabled。 this

defaultConfig { ... multiDexEnabled true ... } spa

如今,根据你的项目状况,你有3种选择:

  1. 若是你没有建立本身的Application 类,在你的清单文件AndroidManifest.xml中配置android.support.multidex.MultiDexApplication就能够了。

    .... android:name="android.support.multidex.MultiDexApplication" ...

  2. 若是你有本身的Application类了,让它继承 android.support.multidex.MultiDexApplication而不是android.app.Application
  3. 若是你的Application继承了其余的类,而且你不想改变或者没办法改变。按照下面的方法重写attachBaseContext()

    public class MyApplication extends FooApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }

不论你选择上面哪一种,都会建立多个大小差很少的dex文件代替单个庞大的dex文件。运行的时候回同事加载全部的这些dex文件。

当年编译app的时候,Gradle会生成不少个dex文件和一个apk文件让你能够在设备或者模拟器上运行。

enter image description here
你能够从这个项目看到上面的效果

注意事项

Out of memory 问题 
对于有不少依赖的项目,编译可能由于下面的错误中断

Error:Execution failed for task ':app:dexDebug'. ... Error Code: 3 Output: UNEXPECTED TOP-LEVEL ERROR: java.lang.OutOfMemoryError: GC overhead limit exceeded at com.android.dx.cf.cst.ConstantPoolParser.parse0(ConstantPoolParser.java:326) ...

在build.gralde android标签下面添加下面代码能够解决

dexOptions { incremental true javaMaxHeapSize "4g" }

应用启动缓慢 
根据咱们的经验,添加了这个支持库之后,大多数状况下都正常了。这对某些设备,好比Kindle Fire上面,应用启动会比以前慢不少。加载全部的类在应用一启动的时候会花费大量的时间。这就会致使黑屏一段时间,甚至致使ANR.

更多推荐方案点击这里

结论

这个虽然在大多数时候能够解决DEX 64K的问题,可是应该是保留使用。当你尝试使用它之前,请先尝试删除不须要的依赖而且使用ProGuard混淆,若是你必需要使用这个方案。请确保在旧设备上作了测试。

相关文章
相关标签/搜索