Android DEX方法超过64K和gradle编译OOM解决方案

来源:互联网 发布:mysql 高级sql语句 编辑:程序博客网 时间:2024/05/29 17:19

首先贴上报错信息:Error:Execution failed for task ':app:transformClassesWithDexForDebug'.> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_60\bin\java.exe'' finished with non-zero exit value 2

使用Android studio开发的小伙伴肯定都会遇到过这个错误,出现这个错误一般情况是项目中存在冲突了,我一看到这个错误的时候好淡定,因为本人之前遇到过,就是lib里面存在有重复的jar库文件,于是第一时间就去检查自己的lib下是否存在有重复的jar文件,于是检查半天发现并没有重复的jar,于是查看build.gradle文件dependencies是否有重复的,可是还是没发现有重复的.到网上各种百度,各种谷歌,大多数会说是加载有重复的jar文件,或者是jdk版本的问题(其实出现这个问题一般跟jdk版本是没多大关系的).

一直寻找编译不过的原因,于是我把代码恢复到之前的版本,发现项目可以编译通过毫无问题,只要加入新代码就出现这个问题,于是我有重复地检查我的代码是否有什么问题,检查了N次依然不知道是什么原因,后面我尝试着删除最新加入的一个JavaBean 类,可以编译通过.感觉到问题好奇怪,于是我就想是不是项目中dex方法超过了64K的上限,通过多次反复的验证,我最终确定果然是这个问题.这就坑爹了,这报错报的那么笼统,对于第一次遇到这种问题的我真的是够了.

错误的原因是这样的,在一个DEX文件,你可以调用很多的方法,但你只能调用它们最前面的65,536个 ,因为这是在方法调用集合中的所有的空间了。Google提供一套官方的解决方案,在10月14日的时候发布了MultiDex 支持库,随后几周gradle在 v0.14.0版本中也支持了。如果你在使用 Android Studio,这个用起来很简单。如果不是,强烈建议你迁移过来。因为Google很快就会不知处Eclipse插件和旧的基于Ant的系统构建方式。

下面是解决这个问题的步骤:

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

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

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

defaultConfig {    ...     multiDexEnabled true     ... }

现在,根据你的项目情况,你有3种选择:

  1. 如果你没有创建自己的Application 类,在你的清单文件AndroidManifest.xml中配置android.support.multidex.MultiDexApplication就可以了。

       ....    android:name="android.support.multidex.MultiDexApplication"    ... 
  2. 如果你有自己的Application类了,让它继承 android.support.multidex.MultiDexApplication而不是android.app.Application,并在你的Application类添加下面方法
     @Override      protected void attachBaseContext(Context base) {         super.attachBaseContext(base);         MultiDex.install(this);      } 

  1. 如果你的Application继承了其他的类,并且你不想改变或者没办法改变。按照下面的方法重写attachBaseContext()

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

不论你选择上面哪种,都会创建多个大小差不多的dex文件代替单个庞大的dex文件。运行的时候回同加载所有的这些dex文件。

当你做了上面的配置之后再次进行编译,那也不一定能编译通过,可能会出现另外一个错误:

java.lang.OutOfMemoryError: GC overhead limit exceeded

Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_60\bin\java.exe'' finished with non-zero exit value 3

对于有很多依赖的项目,编译可能因为下面的错误中断

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" }


0 0
原创粉丝点击