Wenn Ihre App eine minSdk
von API 20 oder niedriger hat und Ihre App und die
Bibliotheken, auf die sie verweist, 65.536 Methoden überschreitet, tritt der folgende Build-Fehler auf,
gibt an, dass Ihre App das Limit der Android-Build-Architektur erreicht hat:
trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.
Ältere Versionen des Build-Systems melden einen anderen Fehler, der auf denselben Fehler hinweist. Problem:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
Für diese Fehlerbedingungen wird eine allgemeine Zahl angezeigt: 65536. Diese Nummer stellt die Gesamtzahl der Referenzen dar, durch den Code in einer einzelnen Dalvik Executable (DEX)-Bytecode-Datei aufgerufen wird. Auf dieser Seite wird erläutert, wie Sie diese Einschränkung Mit der sogenannten Multidex-App-Konfiguration um mehrere DEX-Dateien zu erstellen und zu lesen.
Referenzlimit von 64.000
Android-App-Dateien (APKs) enthalten ausführbare Bytecode-Dateien im Format von Dalvik Ausführbare Dateien (DEX), die den kompilierten Code zum Ausführen Ihrer Anwendung enthalten. Die Dalvik Executable-Spezifikation begrenzt die Gesamtzahl der Methoden, die kann in einer einzelnen DEX-Datei bis 65.536 – einschließlich Android – Framework-Methoden, Bibliotheksmethoden und Methoden in Ihrem eigenen Code.
Im Kontext der Informatik für den Begriff Kilo oder K für 1024 (oder 2^10). Da 65.536 64x1024 entspricht, wird diese Begrenzung _64.000 Referenzlimit_.Unterstützung von Multidex vor Android 5.0
In Versionen der Plattform vor Android 5.0 (API-Level 21) wird die Dalvik-Technologie verwendet
Laufzeit zum Ausführen des App-Codes. Standardmäßig beschränkt Dalvik Apps auf eine
classes.dex
Bytecode-Datei pro APK. Um das Problem zu umgehen
fügen Sie die Multidex-Bibliothek zu build.gradle
auf Modulebene hinzu oder
build.gradle.kts
Datei:
Cool
dependencies { def multidex_version = "2.0.1" implementation "androidx.multidex:multidex:$multidex_version" }
Kotlin
dependencies { val multidex_version = "2.0.1" implementation("androidx.multidex:multidex:$multidex_version") }
Diese Bibliothek wird Teil der primären DEX-Datei Ihrer App und verwaltet den Zugriff auf die zusätzlichen DEX-Dateien und den darin enthaltenen Code. Die aktuellen Versionen für diese Bibliothek finden Sie unter Multidex-Versionen.
Weitere Informationen finden Sie im Abschnitt zur konfiguriere deine App für Multidex.Multidex-Unterstützung für Android 5.0 und höher
Android 5.0 (API-Level 21) und höher verwendet eine Laufzeit mit dem Namen ART, die
unterstützt das Laden mehrerer DEX-Dateien aus APK-Dateien. Kunst
Bei der App-Installation wird eine Vorkompilierung durchgeführt und nach
classesN.dex
-Dateien und kompiliert sie in einer einzigen Datei
OAT-Datei für
die das Android-Gerät ausführt. Wenn also Ihre minSdkVersion
21 oder höher ist, ist Multidex standardmäßig aktiviert und Sie benötigen die Multidex-Bibliothek nicht.
Weitere Informationen zu Android 5.0 lesen Sie Android Runtime (ART) und Dalvik.
Hinweis:Wenn Sie Ihre App mit Android Studio ausführen, ist der Build für die Zielgeräte optimiert, auf denen Sie die Bereitstellung vornehmen. Dazu gehört auch das Aktivieren von Multidex, wenn die Zielgeräte ausgeführt werden Android 5.0 und höher. Da diese Optimierung nur angewendet wird, wenn Ihre Anwendung mit Android Studio müssen Sie möglicherweise noch Ihren Release-Build konfigurieren. um die 64.000-Grenze zu umgehen.
Das Limit von 64.000 KB vermeiden
Bevor Sie Ihre App für die Verwendung von 64K oder mehr Methodenreferenzen konfigurieren, sollten Sie Folgendes tun um die Gesamtzahl der von Ihrem App-Code aufgerufenen Verweise zu reduzieren, einschließlich der durch Ihren App-Code oder enthaltene Bibliotheken.
Die folgenden Strategien können Ihnen helfen, das Erreichen des DEX-Referenzlimits zu vermeiden:
- Direkte und transitive Abhängigkeiten Ihrer App überprüfen
- Überlegen Sie, ob der Wert einer großen Bibliotheksabhängigkeit, die Sie in Ihre App aufnehmen, die Menge an Code überwiegt. die der App hinzugefügt werden. Ein häufiges, aber problematisches Muster ist die Einbindung einer sehr großen Bibliothek. da einige Dienstprogrammmethoden nützlich waren. Die Reduzierung der Abhängigkeiten Ihres App-Codes kann oft helfen, Sie vermeiden das DEX-Referenzlimit.
- Ungenutzten Code mit R8 entfernen
- Codekomprimierung aktivieren, um R8 auszuführen für Ihre Release-Builds. Aktivieren Sie die Verkleinerung, mit Ihren APKs keinen ungenutzten Code versenden. Wenn die Codekomprimierung richtig konfiguriert ist, können Sie auch nicht verwendeten Code und nicht verwendete Ressourcen aus Ihren Abhängigkeiten entfernen.
Mit diesen Methoden können Sie die Gesamtgröße Ihres APK verringern und ohne Multidex in Ihrer App verwenden zu müssen.
App für Multidex konfigurieren
Hinweis: Wenn deineminSdkVersion
auf 21 oder höher eingestellt ist, ist Multidex standardmäßig aktiviert.
und Sie brauchen die Multidex-Bibliothek nicht.
Wenn Ihre minSdkVersion
auf 20 oder niedriger eingestellt ist,
muss die Methode
Multidex-Bibliothek und
die folgenden Änderungen an Ihrem App-Projekt vorgenommen haben:
-
Ändern Sie die Datei
build.gradle
auf Modulebene zu Aktivieren Sie Multidex und fügen Sie die Multidex-Bibliothek als Abhängigkeit hinzu, wie hier gezeigt:Cool
android { defaultConfig { ... minSdkVersion 15 targetSdkVersion 33 multiDexEnabled true } ... } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Kotlin
android { defaultConfig { ... minSdk = 15 targetSdk = 33 multiDexEnabled = true } ... } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
- Je nachdem, ob Sie den
Application
führen Sie einen der folgenden Schritte aus: <ph type="x-smartling-placeholder">- </ph>
Wenn Sie
Application
nicht überschreiben -Klasse, bearbeiten Sie Ihre Manifestdatei und legen Sieandroid:name
im<application>
-Tag so an:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application android:name="androidx.multidex.MultiDexApplication" > ... </application> </manifest>
Wenn Sie die
Application
überschreiben, Klasse, ändern Sie sie so, dassMultiDexApplication
erweitert wird:Kotlin
class MyApplication : MultiDexApplication() {...}
Java
public class MyApplication extends MultiDexApplication { ... }
Wenn Sie den
Application
überschreiben aber die Basisklasse kann nicht geändert werden. überschreiben Sie stattdessen die MethodeattachBaseContext()
und rufen Sie zum AktivierenMultiDex.install(this)
auf. Multidex:Kotlin
class MyApplication : SomeOtherApplication() { override fun attachBaseContext(base: Context) { super.attachBaseContext(base) MultiDex.install(this) } }
Java
public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }
Achtung:Nicht ausführen
MultiDex.install()
oder einem anderen Code durch Reflexion oder JNI, bevorMultiDex.install()
abgeschlossen ist. Bei der Multidex-Verfolgung diesen Aufrufen nicht folgen,ClassNotFoundException
verursachen oder Fehler überprüfen aufgrund einer fehlerhaften Klassenpartition zwischen DEX-Dateien.
Wenn Sie jetzt Ihre App erstellen, erstellen die Android-Build-Tools einen primären DEX.
Datei (classes.dex
) und unterstützende DEX-Dateien
(classes2.dex
, classes3.dex
usw.) nach Bedarf.
Das Build-System verpackt dann alle DEX-Dateien in dein APK.
Zur Laufzeit suchen Sie dann nicht nur in der Haupt-,
classes.dex
-Datei verwenden, verwenden die Multidex-APIs ein spezielles Klassenladeprogramm, um alle
verfügbaren DEX-Dateien für Ihre Methoden.
Einschränkungen der Multidex-Bibliothek
Für die multidex-Bibliothek gelten einige bekannte Einschränkungen. Wenn Sie die Bibliothek in die Build-Konfiguration Ihrer App einbinden, beachten Sie Folgendes:
- Die Installation von DEX-Dateien beim Start auf der Datenpartition eines Geräts ist komplex und Wenn die sekundären DEX-Dateien groß sind, kann es zu ANR-Fehlern (App antwortet nicht) kommen. Bis aktivieren Sie das Verkleinern von Code, die Größe von DEX-Dateien zu reduzieren und nicht verwendete Codeteile zu entfernen.
- Bei Ausführung auf Versionen vor Android 5.0 (API-Level 21) mit
multidex reicht nicht aus, um den Linearalloc-Grenzwert zu umgehen (issue 37008143). Dieses Limit wurde erhöht in
Android 4.0 (API-Level 14), aber dadurch wurde das Problem nicht vollständig behoben.
Bei älteren Versionen als Android 4.0 können Sie DEX-Indexlimit erreicht. Wenn Sie eine Ausrichtung auf API-Ebenen vornehmen, die niedriger sind als 14. Testen Sie diese Versionen der Plattform gründlich, da Ihre App Probleme beim Start oder beim Laden bestimmter Gruppen von Klassen auftreten.
Die Codeverkleinerung kann die diese Probleme beheben können.
Deklarieren Sie die erforderlichen Klassen in der primären DEX-Datei
Beim Erstellen der einzelnen DEX-Dateien für eine Multidex-App führen die Build-Tools eine
komplexe Entscheidungsfindung, um zu bestimmen, welche Klassen im primären DEX benötigt werden.
-Datei, damit Ihre Anwendung erfolgreich gestartet werden kann. Erforderliche Kurse
nicht in der primären DEX-Datei angegeben ist, stürzt die App
mit dem Fehler java.lang.NoClassDefFoundError
.
Die Build-Tools erkennen die Codepfade für Code, auf den direkt aus Ihrer App zugegriffen wird. Code. Dieses Problem kann jedoch treten auf, wenn die Codepfade weniger sichtbar sind, z. B. wenn eine von Ihnen verwendete Bibliothek und komplexe Abhängigkeiten. Wenn in dem Code z. B. Introspektion oder Aufruf verwendet wird, von Java-Methoden aus nativem Code, dann werden diese Klassen möglicherweise nicht als in der primären DEX-Datei erforderlich ist.
Wenn du java.lang.NoClassDefFoundError
erhältst,
muss die im primären DEX erforderlichen zusätzlichen Klassen manuell angeben
indem Sie sie mit dem Attribut multiDexKeepProguard
in Ihrem Build-Typ deklarieren. Wenn ein Kurs in
der Datei multiDexKeepProguard
, dann wird diese Klasse
wird der primären DEX-Datei hinzugefügt.
multiDexKeepProguard-Property
Die Datei multiDexKeepProguard
hat dasselbe Format wie ProGuard und unterstützt die
gesamte ProGuard-Grammatik. Weitere Informationen dazu, wie Sie festlegen können, was in Ihrer App gespeichert wird, finden Sie unter
Festlegen, welcher Code beibehalten werden soll
Die Datei, die Sie in multiDexKeepProguard
angeben, muss -keep
enthalten.
-Optionen in einer beliebigen gültigen ProGuard-Syntax. Beispiel:
-keep com.example.MyClass.class
Sie können eine Datei mit dem Namen
multidex-config.pro
sieht so aus:
-keep class com.example.MyClass -keep class com.example.MyClassToo
Wenn Sie alle Klassen in einem Paket angeben möchten, sieht die Datei so aus:
-keep class com.example.** { *; } // All classes in the com.example package
So deklarieren Sie diese Datei für einen Build-Typ:
Cool
android { buildTypes { release { multiDexKeepProguard file('multidex-config.pro') ... } } }
Kotlin
android { buildTypes { getByName("release") { multiDexKeepProguard = file("multidex-config.pro") ... } } }
Multidex in Entwicklungs-Builds optimieren
Eine Multidex-Konfiguration erfordert eine deutlich erhöhte Build-Verarbeitung da das Build-System komplexe Entscheidungen darüber treffen muss, welche Klassen muss in der primären DEX-Datei enthalten sein und welche Klassen in sekundäre DEX-Dateien. Inkrementelle Builds mit Multidex und kann den Entwicklungsprozess verlangsamen.
Um längere inkrementelle Build-Zeiten abzumildern, verwenden Sie
Predexing zur Wiederverwendung der Multidex-Ausgabe zwischen Builds
Das Predexing basiert auf einem ART-Format, das nur unter Android 5.0 verfügbar ist.
(API-Level 21) und höher. Wenn Sie Android Studio verwenden, verwendet die IDE automatisch Predexing
wenn Sie Ihre App auf einem Gerät mit Android 5.0 (API-Level 21) oder höher bereitstellen.
Wenn Sie jedoch Gradle-Builds über die Befehlszeile ausführen, müssen Sie den Parameter
minSdkVersion
auf 21 oder höher, um das Pre-Dexing zu aktivieren.
minSdkVersion
,
wie hier gezeigt:
Cool
android { defaultConfig { ... multiDexEnabled true // The default minimum API level you want to support. minSdkVersion 15 } productFlavors { // Includes settings you want to keep only while developing your app. dev { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdkVersion 21 } prod { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Kotlin
android { defaultConfig { ... multiDexEnabled = true // The default minimum API level you want to support. minSdk = 15 } productFlavors { // Includes settings you want to keep only while developing your app. create("dev") { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdk = 21 } create("prod") { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } } } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
Weitere Strategien zur Verbesserung der Build-Geschwindigkeit über Android Studio oder den Befehl Build-Geschwindigkeit optimieren. Weitere Informationen zur Verwendung von Build-Varianten finden Sie unter Build-Varianten konfigurieren
Tipp:Wenn Sie verschiedene Build-Varianten für verschiedene
Multidex-Anforderungen erfüllt, können Sie für jedes
sodass nur die Datei für API-Level 20 und niedriger
<application>
-Tag-Name. Sie können auch
Erstellen Sie für jede Variante eine eigene Application
-Unterklasse,
nur die abgeleitete Klasse für API-Level 20 und niedriger erweitert die MultiDexApplication
-Klasse oder
ruft MultiDex.install(this)
auf.
Multidex-Apps testen
Wenn Sie Instrumentierungstests für Multidex-Apps schreiben, ist keine zusätzliche Konfiguration erforderlich
wenn Sie eine
<ph type="x-smartling-placeholder"></ph>
MonitoringInstrumentation
oder ein
<ph type="x-smartling-placeholder"></ph>
AndroidJUnitRunner
Instrumentierung. Wenn Sie eine andere
Instrumentation
,
dann müssen Sie die onCreate()
-Methode mit dem folgenden Code überschreiben:
Kotlin
fun onCreate(arguments: Bundle) { MultiDex.install(targetContext) super.onCreate(arguments) ... }
Java
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ... }