Android DEX方法超過64K和gradle編譯OOM解決方案
首先貼上報錯資訊: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種選擇:
-
如果你沒有建立自己的Application 類,在你的清單檔案AndroidManifest.xml中配置
android.support.multidex.MultiDexApplication
就可以了。.... android:name="android.support.multidex.MultiDexApplication" ...
- 如果你有自己的Application類了,讓它繼承
android.support.multidex.MultiDexApplication
而不是android.app.Application,並在你的Application類新增下面方法
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
-
如果你的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"
}