https://developer.android.com/studio/build/multidex.html#about
隨著 Android 平臺的持續(xù)成長浴韭,Android 應(yīng)用的大小也在增加狞玛。當您的應(yīng)用及其引用的庫達到特定大小時,您會遇到構(gòu)建錯誤浩姥,指明您的應(yīng)用已達到 Android 應(yīng)用構(gòu)建架構(gòu)的極限。早期版本的構(gòu)建系統(tǒng)按如下方式報告這一錯誤:
Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536
較新版本的 Android 構(gòu)建系統(tǒng)雖然顯示的錯誤不同,但指示的是同一問題:
trouble writing output:Too many field references: 131000; max is 65536.You may try using --multi-dex option.
這些錯誤狀況都會顯示下面這個數(shù)字:65,536相味。這個數(shù)字很重要尼酿,因為它代表的是單個 Dalvik Executable (DEX) 字節(jié)碼文件內(nèi)的代碼可調(diào)用的引用總數(shù)爷狈。本頁介紹如何通過啟用被稱為?Dalvik 可執(zhí)行文件分包的應(yīng)用配置來越過這一限制,使您的應(yīng)用能夠構(gòu)建并讀取 Dalvik 可執(zhí)行文件分包 DEX 文件裳擎。
關(guān)于 64K 引用限制
Android 應(yīng)用 (APK) 文件包含?Dalvik?Executable (DEX) 文件形式的可執(zhí)行字節(jié)碼文件涎永,其中包含用來運行您的應(yīng)用的已編譯代碼。Dalvik Executable 規(guī)范將可在單個 DEX 文件內(nèi)可引用的方法總數(shù)限制在 65,536,其中包括 Android 框架方法羡微、庫方法以及您自己代碼中的方法谷饿。在計算機科學領(lǐng)域內(nèi),術(shù)語千(簡稱 K)表示 1024(或 2^10)妈倔。由于 65,536 等于 64 X 1024博投,因此這一限制也稱為“64K 引用限制”。
如果您的?minSdkVersion?為 21 或更高值盯蝴,則不需要 Dalvik 可執(zhí)行文件分包支持庫毅哗。
Android 5.0(API 級別 21)之前的平臺版本使用 Dalvik 運行時來執(zhí)行應(yīng)用代碼。默認情況下捧挺,Dalvik 限制應(yīng)用的每個 APK 只能使用單個?classes.dex?字節(jié)碼文件虑绵。要想繞過這一限制,您可以使用?Dalvik 可執(zhí)行文件分包支持庫闽烙,它會成為您的應(yīng)用主要 DEX 文件的一部分翅睛,然后管理對其他 DEX 文件及其所包含代碼的訪問。
Android 5.0 及更高版本的 Dalvik 可執(zhí)行文件分包支持
Android 5.0(API 級別 21)及更高版本使用名為 ART 的運行時黑竞,后者原生支持從 APK 文件加載多個 DEX 文件宏所。ART 在應(yīng)用安裝時執(zhí)行預(yù)編譯,掃描classesN.dex?文件摊溶,并將它們編譯成單個?.oat?文件爬骤,供 Android 設(shè)備執(zhí)行。因此莫换,如果您的?minSdkVersion?為 21 或更高值霞玄,則不需要 Dalvik 可執(zhí)行文件分包支持庫。
注:如果將應(yīng)用的?minSdkVersion?設(shè)置為 21 或更高值拉岁,使用?Instant Run?時坷剧,Android Studio 會自動將應(yīng)用配置為進行 Dalvik 可執(zhí)行文件分包。由于 Instant Run 僅適用于調(diào)試版本的應(yīng)用喊暖,您仍需配置發(fā)布構(gòu)建進行 Dalvik 可執(zhí)行文件分包惫企,以規(guī)避 64K 限制。
規(guī)避 64K 限制
在將您的應(yīng)用配置為支持使用 64K 或更多方法引用之前陵叽,您應(yīng)該采取措施減少應(yīng)用代碼調(diào)用的引用總數(shù)狞尔,包括由您的應(yīng)用代碼或包含的庫定義的方法。下列策略可幫助您避免達到 DEX 引用限制:
檢查您的應(yīng)用的直接和傳遞依賴項?- 確保您在應(yīng)用中使用任何龐大依賴庫所帶來的好處大于為應(yīng)用添加大量代碼所帶來的弊端巩掺。一種常見的反面模式是偏序,僅僅為了使用幾個實用方法就在應(yīng)用中加入非常龐大的庫。減少您的應(yīng)用代碼依賴項往往能夠幫助您規(guī)避 dex 引用限制胖替。
通過 ProGuard 移除未使用的代碼?- 為您的版本構(gòu)建啟用代碼壓縮以運行 ProGuard研儒。啟用壓縮可確保您交付的 APK 不含有未使用的代碼豫缨。
使用這些技巧使您不必在應(yīng)用中啟用 Dalvik 可執(zhí)行文件分包,同時還會減小 APK 的總體大小端朵。
配置您的應(yīng)用進行 Dalvik 可執(zhí)行文件分包
將您的應(yīng)用項目設(shè)置為使用 Dalvik 可執(zhí)行文件分包配置需要對您的應(yīng)用項目進行以下修改好芭,具體取決于應(yīng)用支持的最低 Android 版本。
如果您的?minSdkVersion?設(shè)置為 21 或更高值冲呢,您只需在模塊級?build.gradle?文件中將?multiDexEnabled?設(shè)置為?true栓撞,如此處所示:
android {
defaultConfig{...
minSdkVersion ?21
targetSdkVersion ?26
multiDexEnabled true
}...}
但是,如果您的?minSdkVersion?設(shè)置為 20 或更低值碗硬,則您必須按如下方式使用?Dalvik 可執(zhí)行文件分包支持庫:
修改模塊級?build.gradle?文件以啟用 Dalvik 可執(zhí)行文件分包瓤湘,并將 Dalvik 可執(zhí)行文件分包庫添加為依賴項,如此處所示:
android {
defaultConfig
{...
minSdkVersion ?15
targetSdkVersion ??26
multiDexEnabled true ?
}...}
dependencies{
compile 'com.android.support:multidex:1.0.1'
}
根據(jù)是否要替換?Application?類恩尾,執(zhí)行以下操作之一:
如果您沒有替換?Application?類弛说,請編輯清單文件,按如下方式設(shè)置 <?application>標記中的?android:name:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
? ? ? ? ? ? ? ? ? package="com.example.myapp">
<application ?android:name="android.support.multidex.MultiDexApplication"?>
</application>
</manifest>
如果您替換了?Application?類翰意,請按如下方式對其進行更改以擴展?MultiDexApplication(如果可能):
public class MyApplication extends MultiDexApplication { ... }
或者木人,如果您替換了?Application?類,但無法更改基本類冀偶,則可以改為替換?attachBaseContext()?方法并調(diào)用?MultiDex.install(this)?來啟用 Dalvik 可執(zhí)行文件分包:
public class MyApplication extends SomeOtherApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(context);Multidex.install(this);
}
}