Android開發的朋友,遇到很多這樣的情況,隨著功能的增加,方法數增多,就會出現所謂的64k方法數問題。
產生原因
Android APK文件本質上是一個壓縮文件,它包含的classes.dex文件是Dalvik字節碼文件,這個dex文件中存放的就是編譯后的Java代碼。Dalvik可執行文件規范限制了單個.dex文件最多引用的方法數是65536個。
MultiDex的使用
google為了規避上述問題,推出了MultiDex解決方案解決方法數超限問題
配置build.gradle
android {
compileSdkVersion 21
buildToolsVersion "21.1.0"http://必須使用21或之后的版本
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 21
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
配置Application
如果用戶沒有重寫Application,只需修改Manifest文件中的內容:
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
如果用戶繼承變重寫了Application,可以將繼承的Application換成MultiDexApplication。
或者重寫attachBaseContext() 方法,
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
特別注意,如果沒有實現這部分代碼,運行時會出現NoClassDefFoundError的錯誤,尤其是在依賴三方函數庫時。
解決原理
Android5.0之前
Dalvik在5.0之前,為每一個APK只生成一個classes.dex,所以會有上述所說的方法數超限的問題,如果我們可以將一個dex文件分成多個,在應用啟動時,加載第一個(主dex)dex文件,當啟動以后,再依次加載其他dex文件。這樣就可以規避上述問題了。MultiDex即是實現了這樣的功能
Android5.0之后
Android5.0及更高版本使用支持從apk中加載多個dex文件的ART運行時機制,在應用安裝時,加載classed(…N).dex文件并編譯成一個.oat文件以支持在Android設備上運行。
MultiDex與NoClassDefFoundError
這個問題之前出現過很多次,當時是由于配置了build.gradle文件但是沒有使用MultiDexApplication造成的。所以開發者一定要記得使用MultiDexApplication或者MultiDex.install(this),具體參考上面提到過的配置Application。
還有一種情況,上面提到過的,使用MultiDex機制,必然存在主dex文件和從dex文件,應用啟動時所需要的類,都應放入主dex中,否則也會出現NoClassDefFoundError。這種情況可以手動添加一些類到主dex中:
- multiDexKeepFile
手動加入要放到Main.dex中的類。
android/support/multidex/MultiDex.class
- multiDexKeepProguard
以Proguard的方式手動加入要放到Main.dex中的類。
-keep class android.support.multidex.** {
*;
}
然后在build.gradle中進行配置:
android {
defaultConfig {
multiDexEnabled true
multiDexKeepProguard file('multiDexKeep.pro')
multiDexKeepFile file('multiDexKeep.txt')
}
}
dependencies {
compile'com.android.support:multidex:1.0.1'
}
優化Multidex的開發和構建
multidex會加長構建應用的時間,這個必要的過程可能會拖慢你的開發進度。 為加速構建過程,我們可以在Gradle中配置productFlavors,如果對這個不熟悉的開發者可以參考我之前的一篇文章,很詳細的介紹了productFlavors——Android工程gradle詳解
開發時將minSdkVersion改為21使用ART運行時機制,這樣能加快構建速度。release時改為合適的minSdkVersion,這樣僅在release時費時較長。
build.gradle配置如下:
android {
productFlavors {
dev {
minSdkVersion 21
}
prod {
minSdkVersion 14
}
}
...
buildTypes {
release {
...
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
完成上述配置后,你可以使用結合了dev productFlavor和buildType屬性的devDebug變體app。
這個變體app包含如下特性:
- 關閉了混淆(proguard)
- 支持multidex
- minSdkVersion 設置為 Android API level 21.
值得注意的是:上述配置后的devDebug變種app僅能運行在Android 5.0設備上。
.