天天看點

配置android app 方法數超過65k問題

也可以關注我的公衆号随着android平台的增長,同樣你的應用也在疊代中,當你的app或者你應用的庫到達一定的規模時,當我們build的時候很容易達到android的65k限制,早期build時的錯誤提示如下

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

最近幾個版本中build時的錯誤提示如下

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

這兩種錯誤情況顯示一個共同的數字:65,536。這個數字是在它代表一個Dalvik可執行(DEX)位元組碼檔案中調用或引用的方法總數。如果你已經建立了一個Android應用程式,并收到此錯誤,那麼恭喜你,你的代碼超過了一個DEX檔案的限制!本文檔介紹了如何将突破這個限制,并繼續建構應用程式。

1,關于64K參考限值

Android應用(APK)檔案包含在可執行的Dalvik(DEX)檔案,其中包含用于運作你的應用程式的編譯代碼形式的可執行位元組碼檔案。在Dalvik可執行的規範限制了可以在單個檔案DEX内引用到65536,包括Android架構方法,庫方法,并在自己的代碼方式方法的總數。在計算機科學的上下文中,術語基洛,K表示1024(2 ^10)。因為65,536等于64×1024,這個限制被稱為’64K參考限制’。

如果想突破此限制,您需要配置您的應用程式的建構過程,生成多個檔案DEX,被稱為multidex配置。

2,Multidex支援到Android5.0之前

之前的Android5.0(API級别21)平台的版本,用于執行應用程式代碼的Dalvik運作。預設情況下,Dalvik的限制應用到每個APK一個classes.dex位元組碼檔案。為了解決這個限制,可以使用multidex支援庫,成為您的應用程式的主DEX檔案的一部分,然後設法獲得額外的DEX檔案和它們所包含的代碼。

注意:如果您的項目配置為multidex用的minSdkVersion20或更低,并且部署到目标運作Android4.4(API級别20)或更低的裝置,Android Studio中禁用即時運作。

3,為Android5.0及更高版本Multidex支援

Android 5.0(API級别21)和較高的使用一種稱為ART運作時它本身支援與應用程式APK檔案加載多個DEX檔案。 ART在應用程式執行預編譯安裝時它會掃描類(.. N).dex檔案,并将其編譯成由Android裝置執行單一.oat檔案

注意:使用即時運作,當你的應用程式的的minSdkVersion設定為21或更高版本的Android Studio自動配置您的應用程式的multidex。由于即時隻運作與您的應用程式的調試版本的作品,你還需要為multidex配置您的釋出版本,以避免64K限制。

4,避免64K限制

在配置您的應用程式,以便使用64K或以上方法的引用,您應該采取措施,以減少你的應用程式代碼調用引用的總次數,包括您的應用程式代碼或包含的庫定義的方法。以下政策可以幫助您避免擊中DEX參考限值:

檢視應用的直接和傳遞依賴 - 確定任何大庫的依賴關系,你在應用程式的方式,勝過的代碼量被添加到應用程式中使用。一個常見的反模式是包含一個非常大的庫,因為一些實用的方法是有用的。減少你的應用程式代碼依賴性往往可以幫助你避免DEX參考限值。

使用ProGuard删除未使用的代碼 - 為您的應用程式配置ProGuard的設定來運作ProGuard,可以隻對你使用到的code進行編譯,其他的不會加載到dex檔案中

使用這些技術可以幫助您避免使你的應用更多方法引用所需的生成配置的變化。這些步驟還可以降低你的APK,當流量費比較高的情況下,這種方式也是比較可取的

5,在Gradle中配置Multidex

因為要在Android SDK build tools 2.1.1及以後的版本中,Gradle插件才可以直接配置使用multidex,是以在使用之前,確定你的Android SDK build tools版本,可以通過SDK Manager來進行線上更新

編輯Gradle確定multidex可用

android {
    compileSdkVersion 
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...
        minSdkVersion 
        targetSdkVersion 
        ...

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

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

當這些配置設定添加到應用程式,Android編譯工具建構需要一個主DEX(classes.dex)及其配套(classes2.dex,classes3.dex)。然後,建構系統将它們打包成用于配置設定的APK檔案。

注意:如果您的應用程式繼承了Application,則可以覆寫attachBaseContext()方法,并調用MultiDex.install(context);

6, MultiDex的使用限制

當使用MultiDex的時候應該了解一些他的限制和測試

DEX檔案啟動期間安裝到裝置的資料分區是複雜的,并可能導緻在應用無響應(ANR)錯誤如果二次DEX檔案比較大。在這種情況下,你應該使用ProGuard盡量減少DEX檔案的大小,并删除代碼的未使用的部分。

由于Dalvik的l​​inearAlloc錯誤(22586期)multidex可能無法運作,Android 4.0之前的(API級别14)平台版本的裝置啟動應用程式。如果你是早于14 API目标水準,確定執行與這些版本的平台測試您的應用程式可以在啟動時沒問題或當某類class類被加載

使用multidex配置,使非常大的記憶體配置設定請求的應用程式可能在運作時由于Dalvik的l​​inearAlloc限制(問題78035)崩潰。此配置設定限制是在Android 4.0的(API級别14)增加,但應用仍有可能之前的Andr​​oid 5.0(API級别21)碰上在Android版本中此限制。

7,優化Multidex開發版本

一個multidex配置需要Gradle很長的處理時間,因為建構系統必須做出什麼類必須包含在主DEX檔案,哪些類可以包含在二次DEX檔案複雜的決定。這意味着,正常建立與multidex發展過程的一部分執行通常需要更長的時間,并有可能減緩您的開發過程。

為了減輕通常較長的建立multidex輸出時間,你應該建立使用Gradle中的productFlavors的Android插件建構輸出兩個變化:development flavor and a production flavor.

對于development flavor,支援SDK最小版本2.1,采用 ART-supported format,apk Multidex更快

對于 release flavor,最小版本就是project的minSdk,此設定生成APK multidex是與更多的裝置相容,但需要更長的時間來建立。

下面建構配置示例示範了如何設定Gradle:

android {
    productFlavors {
        // Define separate dev and prod product flavors.
        dev {
            // dev utilizes minSDKVersion =  to allow the Android gradle plugin
            // to pre-dex each module and produce an APK that can be tested on
            // Android Lollipop without time consuming dex merging processes.
            minSdkVersion 
        }
        prod {
            // The actual minSdkVersion for the application.
            minSdkVersion 
        }
    }
          ...
    buildTypes {
        release {
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                                                 'proguard-rules.pro'
        }
    }
}
dependencies {
  compile 'com.android.support:multidex:1.0.0'
}
           

完成此配置更改後,您可以使用您的應用程式,它結合了開發productFlavor和調試buildType的屬性devDebug變種。,multidex調試應用程式啟用,并設定的minSdkVersion到Android API21這些設定導緻了Android gradle這個插件來做到以下幾點:

建設作為單獨的DEX檔案的應用程式(包括依賴)的每個子產品。這通常被稱為pre-dexing

確定每個apk中的dex檔案不能修改

最重要的是,子產品DEX檔案将不會合并,是以長期運作計算來确定主DEX檔案的内容是可以避免的。

這些設定會導緻快速,增量編譯,因為隻有修改子產品的DEX檔案重新計算和重新包裝成APK檔案。從這些結果APK建立可用于僅5.0裝置在Android上進行測試。然而,通過實作配置作為flavar後,将保留執行正常的生成與釋放,适當的最低水準SDK和ProGuard的設定的能力。

還可以建構其它變體,包括一個prodDebug變種的建構,這需要更長的時間來建立,但可以用于測試開發之外。在所示的配置中,prodRelease變異将是最後的測試和釋出版本。如果您在指令行中執行任務的gradle,您可以使用帶有DevDebug标準指令追加到結尾(例如./gradlew installDevDebug)。

提示:您還可以提供定制manifest,每個flavar對應一個application,允許您使用支援庫MultiDexApplication類,或調用MultiDex.install()隻對需要它的變種。

8,在android studio中使用Build Variants

Build Variants可以使用多DEX時,管理建構過程非常有用的。 Android Studio中,您可以選擇在使用者界面建構這些Variants。

有Android Studio中建立自己的應用程式的“devDebug”Variants:

打開從左邊的側邊欄生成Variants視窗。該選項旁邊的收藏夾。

單擊建構變量的名稱,以選擇一個不同的Variants中,如圖1

配置android app 方法數超過65k問題

圖1顯示了建構Variants在Android Studio的左側面闆的螢幕截圖。

注:打開此視窗中的選項隻在您成功同步Gradle build file using the Tools > Android > Sync Project with Gradle Files command.

9,測試 Multidex Apps

當使用儀器測試,multidex應用程式,則需要額外的配置,以使測試儀器。由于代碼在multidex應用類的位置不是一個單一的DEX檔案内,儀表測試不正确除非配置為multidex運作。

為了測試與儀器測試中multidex應用程式,從multidex測試支援庫配置MultiDexTestRunner。下面的示例的build.gradle檔案示範了如何配置您的建構來使用這個測試運作:

android {
  defaultConfig {
      ...
      testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
  }
}
           

當Gradle版本小于1.1時,需要添加multidex-instrumentation:依賴

dependencies {
    androidTestCompile('com.android.support:multidex-instrumentation:1.0.1') {
         exclude group: 'com.android.support', module: 'multidex'
    }
}
           

您可以直接使用 instrumentation test 運作的類或擴充,以滿足您的測試需求。或者,您可以在這樣現有的 instrumentation test 覆寫的onCreate:

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

注:目前不支援multidex建立APK測試使用。

原文來自:

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

也可以關注我的公衆号

配置android app 方法數超過65k問題