Suche…


Einführung

DEX bedeutet ausführbare Bytecode-Dateien von Android-Apps (APK) in Form von Dalvik Executable-Dateien (DEX-Dateien), die den kompilierten Code enthalten, der zum Ausführen Ihrer App verwendet wird.

Die Dalvik Executable-Spezifikation begrenzt die Gesamtzahl der Methoden, die in einer einzelnen DEX-Datei referenziert werden können, auf 65.536 (64 KB). Dies schließt Android-Framework-Methoden, Bibliotheksmethoden und Methoden in Ihrem eigenen Code ein.

Um dieses Limit zu überwinden, müssen Sie den App-Erstellungsprozess so konfigurieren, dass er mehr als eine DEX-Datei generiert, die als Multidex bezeichnet wird.

Bemerkungen

Was ist dex

Dex ist der Name des Dateiformats und der Kodierung, für die Android Java-Code kompiliert wird. In früheren Android-Versionen wurden dex Binärdateien direkt in einer virtuellen Maschine namens Dalvik geladen und ausgeführt. Neuere Versionen von Android verwenden die Android Runtime (ART), die dex Dateien als Zwischendarstellung behandelt und vor dem Ausführen der Anwendung weitere Kompilierungen dex .

Dex ist ein sehr altes Dateiformat in Bezug auf die Lebensdauer von Smartphones und wurde für Geräte entwickelt, deren Hauptspeicher in Dutzenden Megabytes gemessen wurde. Die gestalterischen Einschränkungen dieser Tage sind bis heute geblieben.

Das Problem:

Das dex Dateiformat kodiert eine Begrenzung für die Anzahl der Methoden, die in einer einzelnen Binärdatei referenziert werden können. Da der Teil des Dateiformats, in dem die Anzahl der Verweise gespeichert ist, zwei Byte lang ist, beträgt die maximale Anzahl der Methodenverweise 0xFFFF oder 65535. Wenn eine Anwendung mehr als diese Anzahl von Methodenverweisen enthält, wird die Kompilierung fehlschlagen.

Was Sie dagegen tun können:

Google hat dieses Problem umgangen, genannt Multidex. Es enthält Kompilierungszeit- und Laufzeitkomponenten. Wie der Name schon sagt, wird der Code bei der Kompilierung in eine oder mehrere dex Dateien aufgeteilt. Zur Laufzeit wird dem Standard- ClassLoader wie Klassen aus diesen Dateien ClassLoader werden.

Dieser Ansatz funktioniert gut mit neueren Geräten, weist jedoch einige erhebliche Nachteile auf. Dies kann die Startzeit für Anwendungen erheblich verlängern und auf älteren Geräten kann es zu Fehlern bei der Application Not Responding führen.

Multidex sollte zwar wirksam sein, jedoch möglichst vermieden werden.

Wie man das Limit vermeidet:

Bevor Sie Ihre App für die Verwendung von Methodenreferenzen mit 64 KB oder mehr konfigurieren, sollten Sie die Gesamtzahl der durch Ihren App-Code aufgerufenen Referenzen reduzieren, einschließlich der durch Ihren App-Code oder die enthaltenen Bibliotheken definierten Methoden. Mit den folgenden Strategien können Sie vermeiden, die Dex-Referenzgrenze zu erreichen:

  • Überprüfen Sie die direkten und transitiven Abhängigkeiten Ihrer App - Stellen Sie sicher, dass die Abhängigkeit einer großen Bibliothek, die Sie in Ihre App aufnehmen, auf eine Weise verwendet wird, die die Menge des der Anwendung hinzugefügten Codes überwiegt. Ein häufiges Anti-Pattern ist das Einschließen einer sehr großen Bibliothek, da einige Hilfsmethoden nützlich waren. Durch das Reduzieren der Abhängigkeiten Ihres App-Codes können Sie häufig die Dex-Referenzgrenze vermeiden.
  • Ungenutzten Code mit ProGuard entfernen - Konfigurieren Sie die ProGuard-Einstellungen für Ihre App, um ProGuard auszuführen, und stellen Sie sicher, dass die Verkleinerung für Release-Builds aktiviert ist. Durch das Aktivieren der Verkleinerung wird sichergestellt, dass Sie nicht verwendeten Code mit Ihren APKs versenden.

Der erste Punkt erfordert Sorgfalt und Disziplin des Entwicklers. Bei der Einbindung von Bibliotheken von Drittanbietern muss die Größe der Bibliothek berücksichtigt werden. Zum Beispiel sind zwei beliebte JSON-Bibliotheken Jackson und Gson. Funktionell sind sie sich ziemlich ähnlich, aber Gson sieht in Android einen stärkeren Einsatz. Ein Grund ist, dass Jackson rund 9.000 Methoden wiegt, während Gson 1.900 beiträgt.

Es gibt verschiedene Tools, mit denen Entwickler die Größe ihrer Anwendung nachverfolgen können:

  • dexcount-gradle-plugin meldet die Anzahl der Methodenverweise in Ihrem APK oder AAR in jedem Build
  • dex-method-count ist ein Befehlszeilentool, das die Anzahl der Methodenverweise in einer APK zählt
  • www.methodscount.com ist ein Webservice, der die Methodenreferenzen in jeder APK zählt, die Sie hochladen.

Multidex durch direkte Verwendung von MultiDexApplication

Verwenden Sie diese Option, wenn Sie keine Application benötigen.

Dies ist die einfachste Option, aber auf diese Weise können Sie keine eigene Application bereitstellen. Wenn eine Application benötigt wird, müssen Sie zu einer der anderen Optionen wechseln.

android.support.multidex.MultiDexApplication für diese Option einfach den vollqualifizierten Klassennamen android.support.multidex.MultiDexApplication für die Eigenschaft android:name des application in AndroidManifest.xml an:

<?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>

Multidex durch Erweiterung der Anwendung

Verwenden Sie diese Option, wenn für Ihr Projekt eine Application erforderlich ist.

Geben Sie diese Application mithilfe der android:name -Eigenschaft in der Manifestdatei innerhalb des application .

attachBaseContext() in der Application die attachBaseContext() Methode außer Kraft, und rufen MultiDex.install() in dieser Methode MultiDex.install() :

package com.example;

import android.app.Application;
import android.content.Context;

/**
 * Extended application that support multidex 
 */
public class MyApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

Stellen Sie sicher, dass die Application im application Ihrer AndroidManifest.xml angegeben ist:

<application
    android:name="com.example.MyApplication"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">
</application>

Aktivieren von Multidex

Um eine Multidex-Konfiguration zu ermöglichen, benötigen Sie:

  • um die Gradle Build-Konfiguration zu ändern
  • Verwenden Sie eine MultiDexApplication oder aktivieren Sie die MultiDex in Ihrer Application Klasse

Gradle Konfiguration

In app/build.gradle fügen Sie diese Teile hinzu:

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.1"

    defaultConfig {
        ...
        minSdkVersion 14
        targetSdkVersion 24
        ...

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

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

Aktivieren Sie MultiDex in Ihrer Anwendung

Fahren Sie dann mit einer von drei Optionen fort:

Wenn diese Konfigurationseinstellungen einer App hinzugefügt werden, erstellen die Android-Build-Tools nach Bedarf einen primären Dex (classes.dex) und Unterstützung (classes2.dex, classes3.dex).
Das Build-System packt sie dann zur Verteilung in eine APK-Datei.

Zählmethodenreferenzen für jedes Build (Dexcount Gradle Plugin)

Das dexcount-Plugin zählt Methoden und Klassenressourcen nach einem erfolgreichen Build.

Fügen Sie das Plugin im app/build.gradle :

apply plugin: 'com.android.application'

buildscript {
    repositories {
        mavenCentral() // or jcenter()
    }

    dependencies {
        classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.5.5'
    }
}

Wenden Sie das Plugin in der Datei app/build.gradle :

apply plugin: 'com.getkeepsafe.dexcount'

Suchen Sie nach den vom Plugin generierten Ausgabedaten:

../app/build/outputs/dexcount

Besonders nützlich ist das .html-Diagramm in:

../app/build/outputs/dexcount/debugChart/index.html

Multidex durch Erweiterung von MultiDexApplication

Dies ist sehr ähnlich der Verwendung einer Application und dem Überschreiben der attachBaseContext() Methode.

Bei Verwendung dieser Methode müssen Sie attachBaseContext() jedoch nicht überschreiben, da dies bereits in der MultiDexApplication Superklasse geschieht.

Erweitern Sie MultiDexApplication anstelle von Application :

package com.example;

import android.support.multidex.MultiDexApplication;
import android.content.Context;

/**
 * Extended MultiDexApplication 
 */
public class MyApplication extends MultiDexApplication {

     // No need to override attachBaseContext()

     //..........
}

Fügen Sie diese Klasse genau zu Ihrer AndroidManifest.xml hinzu, als ob Sie Application erweitern würden:

<application
    android:name="com.example.MyApplication"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">
</application>


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow