原因剖析:
在Android系統中,一個App的所有代碼都在一個Dex文件裏面。Dex是一個類似Jar的存儲了多有Java編譯字節碼的歸檔文件。因爲Android系統使用Dalvik虛擬機,所以需要把使用Java Compiler編譯之後的class文件轉換成Dalvik能夠執行的class文件。這裏需要強調的是,Dex和Jar一樣是一個歸檔文件,裏面仍然是Java代碼對應的字節碼文件。當Android系統啓動一個應用的時候,有一步是對Dex進行優化,這個過程有一個專門的工具來處理,叫DexOpt。DexOpt的執行過程是在第一次加載Dex文件的時候執行的。這個過程會生成一個ODEX文件,即Optimised。DexOpt會把每一個類的方法id檢索起來,存在一個鏈表結構裏面。但是這個鏈表的長度是用一個short類型來保存的,導致了方法id的數目不能夠超過65536個。
早期版本的構建系統報告這個錯誤如下:
Conversion to Dalvik format failed:
Unable to execute dex: method ID not in [0, 0xffff]: 65536
最新的一些編譯系統也會報如下錯誤:
trouble writing output:
Too many field references: 131000; max is 65536.
You may try using –multi-dex option.
爲了解決這一問題,官方提出了通過multidex包進行多dex編譯的方法:
1、導入multidex包,設置爲支持多dex輸出模式
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、覆寫Application類
如果你的工程中已經含有Application類,那麼讓它繼承android.support.multidex.MultiDexApplication類,
如果你的Application已經繼承了其他類並且不想做改動,那麼還有另外一種使用方式,覆寫attachBaseContext()方法。
import android.support.multidex.MultiDex;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
這樣處理後,若代碼函數超過65535, 就會生成多個dex文件。不會再報錯。