天天看點

Android配置方法數超過64K的限制

Android配置方法數超過64K的限制

随着 Android 平台的持續成長,Android 應用的大小也在增加。當您的應用及其引用的内容庫達到特定大小時,您會遇到建構錯誤,指明您的應用已達到 Android 應用建構架構的極限。早期版本的建構系統按如下方式報告這一錯誤:

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

較新版本的 Android 建構系統雖然顯示的錯誤不同,但訓示的是同一問題:

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

這些錯誤狀況都會顯示下面這個數字:65536。這個數字很重要,因為它代表的是單個 Dalvik Executable (dex) 位元組碼檔案内的代碼可調用的引用總數。如果您建構的 Android 應用收到了這個錯誤,那麼恭喜您,您有許多代碼了!本文介紹如何越過這一限制,繼續建構您的應用。

關于 64K 引用限制

Android 應用 (APK) 檔案包含 Dalvik Executable (DEX) 檔案形式的可執行位元組碼檔案,其中包含用來運作您的應用的已編譯代碼。Dalvik Executable 規範将可在單個 DEX 檔案内可引用的方法總數限制在 65,536,其中包括 Android 架構方法、内容庫方法以及您自己代碼中的方法。在計算機科學領域内,術語千(簡稱 K)表示 1024(或 2^10)。由于 65,536 等于 64 X 1024,是以這一限制也稱為“64K 引用限制”。

越過這一限制需要您将應用建構流程配置為生成多個 DEX 檔案,這種配置稱為 Dalvik 可執行檔案分包配置。

Android 5.0 之前版本的 Dalvik 可執行檔案分包支援

Android 5.0(API 級别 21)之前的平台版本使用 Dalvik 運作時來執行應用代碼。預設情況下,Dalvik 限制應用的每個 APK 隻能使用單個 classes.dex 位元組碼檔案。要想繞過這一限制,您可以使用 Dalvik 可執行檔案分包支援庫,它會成為您的應用主要 DEX 檔案的一部分,然後管理對其他 DEX 檔案及其所包含代碼的通路。

如果您的項目配置時所面向的 Dalvik 可執行檔案分包使用的是 minSdkVersion 20 或更低版本,并且您将其部署到運作 Android 4.4(API 級别 20)或更低版本系統的目标裝置上,Android Studio 會停用 Instant Run

Android 5.0 及更高版本的 Dalvik 可執行檔案分包支援

Android 5.0(API 級别 21)及更高版本使用名為 ART 的運作時,後者原生支援從應用 APK 檔案加載多個 dex 檔案。ART 在應用安裝時執行預編譯,掃描 classes(..N).dex 檔案,并将它們編譯成單個 .oat 檔案,供 Android 裝置執行。如需了解有關 Android 5.0 運作時的詳細資訊,請參閱 ART 簡介。

如果将應用的 minSdkVersion 設定為 21 或更高,使用 Instant Run 時,Android Studio 會自動将應用配置為進行 Dalvik 可執行檔案分包。由于 Instant Run 僅适用于調試版本的應用,您仍需配置釋出建構進行 Dalvik 可執行檔案分包,以規避 64K 限制。

規避 64K 限制

在将您的應用配置為支援使用64K或更多方法引用之前,您應該采取措施減少應用代碼調用的引用總數,包括由您的應用代碼或包含的内容庫定義的方法。下列政策可幫助您避免達到 dex 引用限制:

  • 檢查您的應用的直接和傳遞依賴項

    確定您在應用中使用任何龐大依賴庫所帶來的好處大于為應用添加大量代碼所帶來的弊端。一種常見的反面模式是,僅僅為了使用幾個實用方法就在應用中加入非常龐大的内容庫。減少您的應用代碼依賴項往往能夠幫助您規避 dex 引用限制。

  • 通過ProGuard移除未使用的代碼

    為您的應用配置 ProGuard 設定以運作 ProGuard,并確定為釋出建構啟用壓縮。啟用壓縮可確定您傳遞的 APK 不含有未使用的代碼。

運用這些技巧可幫助您避免為了在應用中支援更多的方法引用而需要進行的建構配置變更。這些措施還可以減小APK的大小,這對帶寬成本較高的市場特别重要。

通過 Gradle 配置您的應用進行 Dalvik 可執行檔案分包

Android SDK Build Tools 21.1 及更高版本中提供的 Android Plugin for Gradle 支援以 Dalvik 可執行檔案分包作為建構配置的一部分。請您務必使用 SDK 管理器将 Android SDK Build Tools 工具和 Android 支援存儲區更新至最新版本,然後再嘗試配置您的應用進行 Dalvik 可執行檔案分包。

将您的應用開發項目設定為使用 Dalvik 可執行檔案分包配置需要對您的應用開發項目做幾項修改。具體地講,您需要執行以下步驟:

  • 将您的Gradle建構配置更改為啟用Dalvik可執行檔案分包
  • 修改您的清單以引用MultiDexApplication類

修改子產品級 build.gradle 檔案配置以加入支援庫和啟用 Dalvik 可執行檔案分包輸出,如下面這段代碼中所示:

android {
    compileSdkVersion 
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...
        minSdkVersion 
        targetSdkVersion 
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.0'
}
           

在您的清單中,将 Dalvik 可執行檔案分包支援庫中的 MultiDexApplication 類添加到 application 元素中。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>
           

測試 Dalvik 可執行檔案分包應用

編寫面向 Dalvik 可執行檔案分包應用的儀器測試時,無需進行其他配置。使用 MultiDexApplication 或替換您的自定義 Application 對象中的 attachBaseContext() 方法,并調用 MultiDex.install(this) 以啟用 Dalvik 可執行檔案分包。

您也可以替換 Application 中的 onCreate() 方法:

public void onCreate(Bundle arguments) {
    MultiDex.install(getTargetContext());
    super.onCreate(arguments);
    ...
}
           

Dalvik 可執行檔案分包支援庫的局限性

Dalvik 可執行檔案分包支援庫具有一些已知的局限性,将其納入您的應用建構配置之中時,您應該注意這些局限性并進行針對性的測試:

  • 啟動期間向裝置資料分區中安裝 .dex 檔案的過程相當複雜,如果輔助 dex 檔案較大,可能導緻應用無響應 (ANR) 錯誤。在此情況下,您應該通過 ProGuard 運用代碼壓縮技巧來盡量減小 dex 檔案的大小,并移除未使用的那部分代碼。
  • 由于存在 Dalvik linearAlloc 錯誤(問題 22586),使用 Dalvik 可執行檔案分包的應用可能無法在運作的平台版本低于 Android 4.0(API 級别 14)的裝置上啟動。如果您的目标 API 級别小于 14,請務必針對這些版本的平台進行測試,因為您的應用可能會在啟動時或加載特定類群時出現問題。代碼壓縮可以減少甚至有可能消除這些潛在問題。
  • 由于存在 Dalvik linearAlloc 限制(問題 78035),如果使用 Dalvik 可執行檔案分包配置的應用發出非常龐大的記憶體配置設定請求,可能會在運作時發生崩潰。盡管 Android 4.0(API 級别 14)提高了配置設定限制,但在 Android 5.0(API 級别 21)之前的 Android 版本上,應用仍有可能遭遇這一限制。
  • 系統對于主 dex 檔案在 Dalvik 運作時中執行時需要哪些類有着複雜的要求。Android 建構工具更新會處理這些 Android 要求,但所包括的其他内容庫也可能具有其他依賴項要求,包括使用自檢機制,或從原生代碼調用 Java 方法。一些内容庫可能要等到 Dalvik 可執行檔案分包建構工具在更新後允許您對必須包括在主 dex 檔案中的類進行指定時才能使用。

原文位址:配置方法數超過 64K 的應用