Android多包加載

https://developer.android.com/studio/build/multidex.html#about

隨著 Android 平臺(tái)的持續(xù)成長,Android 應(yīng)用的大小也在增加。當(dāng)您的應(yīng)用及其引用的庫達(dá)到特定大小時(shí),您會(huì)遇到構(gòu)建錯(cuò)誤,指明您的應(yīng)用已達(dá)到 Android 應(yīng)用構(gòu)建架構(gòu)的極限。早期版本的構(gòu)建系統(tǒng)按如下方式報(bào)告這一錯(cuò)誤:

Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536

較新版本的 Android 構(gòu)建系統(tǒng)雖然顯示的錯(cuò)誤不同,但指示的是同一問題:

trouble writing output:Too many field references: 131000; max is 65536.You may try using --multi-dex option.

這些錯(cuò)誤狀況都會(huì)顯示下面這個(gè)數(shù)字:65,536。這個(gè)數(shù)字很重要,因?yàn)樗淼氖菃蝹€(gè) 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ùn)行您的應(yīng)用的已編譯代碼。Dalvik Executable 規(guī)范將可在單個(gè) DEX 文件內(nèi)可引用的方法總數(shù)限制在 65,536,其中包括 Android 框架方法、庫方法以及您自己代碼中的方法。在計(jì)算機(jī)科學(xué)領(lǐng)域內(nèi),術(shù)語千(簡稱 K)表示 1024(或 2^10)。由于 65,536 等于 64 X 1024,因此這一限制也稱為“64K 引用限制”。

如果您的?minSdkVersion?為 21 或更高值,則不需要 Dalvik 可執(zhí)行文件分包支持庫。

Android 5.0(API 級(jí)別 21)之前的平臺(tái)版本使用 Dalvik 運(yùn)行時(shí)來執(zhí)行應(yīng)用代碼。默認(rèn)情況下,Dalvik 限制應(yīng)用的每個(gè) APK 只能使用單個(gè)?classes.dex?字節(jié)碼文件。要想繞過這一限制,您可以使用?Dalvik 可執(zhí)行文件分包支持庫,它會(huì)成為您的應(yīng)用主要 DEX 文件的一部分,然后管理對(duì)其他 DEX 文件及其所包含代碼的訪問。

Android 5.0 及更高版本的 Dalvik 可執(zhí)行文件分包支持

Android 5.0(API 級(jí)別 21)及更高版本使用名為 ART 的運(yùn)行時(shí),后者原生支持從 APK 文件加載多個(gè) DEX 文件。ART 在應(yīng)用安裝時(shí)執(zhí)行預(yù)編譯,掃描classesN.dex?文件,并將它們編譯成單個(gè)?.oat?文件,供 Android 設(shè)備執(zhí)行。因此,如果您的?minSdkVersion?為 21 或更高值,則不需要 Dalvik 可執(zhí)行文件分包支持庫。

:如果將應(yīng)用的?minSdkVersion?設(shè)置為 21 或更高值,使用?Instant Run?時(shí),Android Studio 會(huì)自動(dòng)將應(yīng)用配置為進(jìn)行 Dalvik 可執(zhí)行文件分包。由于 Instant Run 僅適用于調(diào)試版本的應(yīng)用,您仍需配置發(fā)布構(gòu)建進(jìn)行 Dalvik 可執(zhí)行文件分包,以規(guī)避 64K 限制。

規(guī)避 64K 限制

在將您的應(yīng)用配置為支持使用 64K 或更多方法引用之前,您應(yīng)該采取措施減少應(yīng)用代碼調(diào)用的引用總數(shù),包括由您的應(yīng)用代碼或包含的庫定義的方法。下列策略可幫助您避免達(dá)到 DEX 引用限制:

檢查您的應(yīng)用的直接和傳遞依賴項(xiàng)?- 確保您在應(yīng)用中使用任何龐大依賴庫所帶來的好處大于為應(yīng)用添加大量代碼所帶來的弊端。一種常見的反面模式是,僅僅為了使用幾個(gè)實(shí)用方法就在應(yīng)用中加入非常龐大的庫。減少您的應(yīng)用代碼依賴項(xiàng)往往能夠幫助您規(guī)避 dex 引用限制。

通過 ProGuard 移除未使用的代碼?- 為您的版本構(gòu)建啟用代碼壓縮以運(yùn)行 ProGuard。啟用壓縮可確保您交付的 APK 不含有未使用的代碼。

使用這些技巧使您不必在應(yīng)用中啟用 Dalvik 可執(zhí)行文件分包,同時(shí)還會(huì)減小 APK 的總體大小。

配置您的應(yīng)用進(jìn)行 Dalvik 可執(zhí)行文件分包

將您的應(yīng)用項(xiàng)目設(shè)置為使用 Dalvik 可執(zhí)行文件分包配置需要對(duì)您的應(yīng)用項(xiàng)目進(jìn)行以下修改,具體取決于應(yīng)用支持的最低 Android 版本。

如果您的?minSdkVersion?設(shè)置為 21 或更高值,您只需在模塊級(jí)?build.gradle?文件中將?multiDexEnabled?設(shè)置為?true,如此處所示:

android {

defaultConfig{...

minSdkVersion ?21

targetSdkVersion ?26

multiDexEnabled true

}...}

但是,如果您的?minSdkVersion?設(shè)置為 20 或更低值,則您必須按如下方式使用?Dalvik 可執(zhí)行文件分包支持庫

修改模塊級(jí)?build.gradle?文件以啟用 Dalvik 可執(zhí)行文件分包,并將 Dalvik 可執(zhí)行文件分包庫添加為依賴項(xiàng),如此處所示:

android {

defaultConfig

{...

minSdkVersion ?15

targetSdkVersion ??26

multiDexEnabled true ?

}...}

dependencies{

compile 'com.android.support:multidex:1.0.1'

}

根據(jù)是否要替換?Application?類,執(zhí)行以下操作之一:

如果您沒有替換?Application?類,請(qǐng)編輯清單文件,按如下方式設(shè)置 <?application>標(biāo)記中的?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?類,請(qǐng)按如下方式對(duì)其進(jìn)行更改以擴(kuò)展?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);

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容