webentwicklung-frage-antwort-db.com.de

Anwendung zu groß? Dex kann nicht ausgeführt werden: Neuer Index kann nicht in eine Nicht-Jumbo-Anweisung eingefügt werden

Beim Kompilieren meiner App wird die folgende Fehlermeldung angezeigt:

[2014-05-07 21:48:42 - Dex Loader] Unable to execute dex: Cannot merge new index 65536 into a non-jumbo instruction!

Ich bin an dem Punkt, dass wenn ich irgendwo in meinem Paket eine neue Methode deklariere / diesen Fehler erhalte. Wenn nicht, wird die App kompiliert.

Ich würde gerne wissen, was genau (und genau) dieser Fehler bedeutet. Meine App ist groß, aber ich glaube nicht, dass sie so groß ist! So:

  • Bedeutet der Fehler, dass ich zu viele Methoden habe? Öffentlichkeit? statisch? Paket? Mitglieder
  • Bezieht es sich auf die Methoden/Mitglieder meines Root-Pakets oder auch auf die enthaltenen JAR-Bibliotheken?
  • Gibt es eine Möglichkeit, weitere Debug-Informationen dazu zu erhalten?

Ich kenne bereits das "Jumbo" -Flagsaktivierungsflag, das in ähnlichen Fragen hier in SO angesprochen wurde. Ich denke jedoch, dass der Jumbo-Modus auf der API-Ebene, auf die ich abziele, nicht verfügbar ist.  

35
rupps

Dies hängt mit der Anzahl der im Projekt enthaltenen Methoden der Bibliotheken zusammen. Wenn Sie beispielsweise in Ihrer App über Tracking verfügen, handelt es sich bei Google Analytics um ~ 7000 Methoden. In einem meiner Projekte, die Lombok (2 MB von JAR) verwenden, gab es diese Probleme. Problem gelöst, diese Bibliothek loszuwerden.

10

Ihr Fehler betrifft die Anzahl der Zeichenfolgen (Methoden, Mitglieder usw.) in einer einzelnen Dex-Datei.

Sie müssen Ihre App mit Jumbo in Dex kompilieren mit:

dex.force.jumbo=true

im project.properties

Dies erhöht das Limit für Zeichenfolgen in Dex-Dateien . Und Ihr Projekt wird wahrscheinlich kompiliert.

Ebenfalls mit Jumbo-Set ist die Grenze von 64K nur für Methoden in einem einzelnen Dex. Wenn Sie dieses Limit in Zukunft erhalten, müssen Sie einige Abhängigkeiten entfernen.

[~ # ~] update [~ # ~]: Für Builds mit Gradle : In Gradle können Sie jumboMode auch in der build.gradle-Datei aktivieren mit:

dexOptions {
    jumboMode = true
}

Check: Android Build: Dex Jumbo-Modus in Gradle

Auch mit Gradle können Sie das 64-KB-Limit für Methoden mit Multidex-Build umgehen, Tutorial hier: https://developer.Android.com/ tools/building/multidex.html

52
fpanizza

Für gradle build fügen Sie einfach die dexOptions in build.gradle ein, um den Jumbo-Modus zu aktivieren:

Android {
    dexOptions {
        jumboMode = true
    }
}

Denken Sie daran, vor Ihrem neuen Gebäude "gradle clean" auszuführen.

24
gary

Anscheinend tritt das Problem auf, weil alle Klassendateien aus Ihrem Projekt und JAR-Dateien vor dem DEXing-Paket zusammen gepackt werden. Dies mag nicht ganz richtig sein, aber es hat sich als sehr schwierig erwiesen, dies in unserem Projekt zu kontrollieren. Selbst das Entfernen von Dingen, die anfangs dieses Problem verursachten, das Bereinigen und Wiederherstellen hat das Problem für uns nicht auf konsistente Weise gelöst.

Daher haben wir diese Gelegenheit genutzt, um unser Projekt auf Android Studio umzustellen und das Problem zu lösen, indem ProGuard für Debug-Builds aktiviert wurde. Genauer gesagt, verwenden wir nur die Schrumpfphase der Prozesskette von ProGuard.

Gradle macht es sehr einfach, ProGuard für Debug-Builds zu aktivieren:

buildTypes {
    debug {
        runProguard true
        proguardFile 'proguard-project-debug.txt'
    }
}

Und hier ist der Debug ProGuard Config, den wir verwenden:

-keep class com.your.code.**
# Use -keep to explicitly keep any other classes shrinking would remove
-dontoptimize
-dontobfuscate
-ignorewarnings

Das erhöht zwar die Erstellungszeit des Projekts, aber die gute Seite ist, dass der Debugger weiterhin funktioniert. 

Die einzige schnellere Alternative, die ich mir vorstellen kann, ist, dass JAR-Dateien manuell von den nicht verwendeten Klassendateien entfernt werden. Dies ist jedoch nicht nur schwierig, es ist auch unpraktisch, wenn Sie später einen etwas größeren Teil einer Bibliothek verwenden möchten.

Ich hoffe, das hilft anderen Entwicklern, die mit diesem Problem zu kämpfen haben. Und vielleicht kann Google den Compiler, der diese Beschneidung standardmäßig vornimmt, in der Zukunft verbessern. Unsere APK-DEX-Datei wurde von 8 MB auf 2,9 MB erhöht.

Neuere Versionen (1.0.0+)

In neueren Versionen von Android Studio (1.0+) wurde der gebündelte Gradle aktualisiert. Es wurden einige Änderungen an der Funktionsweise des Build-Mechanismus vorgenommen, sodass Ihre Gradle-Projektdatei jetzt die Parameter minifyEnabled und shrinkResources nutzen kann. Aktuelle Version ist 1.1.0.

Um mit den Änderungen auf einer sich schnell bewegenden Plattform wie Android Schritt zu halten, ist eine Anstrengung erforderlich, die jedoch häufig mit neuen Funktionen, Tools und schnelleren Bauzeiten belohnt wird. Die Aktualisierung von Android Studio und die (sorgfältige) Aktualisierung Ihrer Projekte ist die Zeit wert, die Sie investieren.

buildTypes {
    debug {
        proguardFile 'proguard-project-debug.txt'
        minifyEnabled true
        shrinkResources true
    }
}
7
omahena

Einige interessante Beobachtungen. Der gleiche Fehler kann auftreten, wenn Sie ein Projekt mit mehreren Projekttypen haben. Es ist verwirrend. Es stellte sich heraus, dass ich versuchte, die App mit dem generischen Befehl auszuführen: gradlew installDebug. Wenn ich die Befehlszeile so geändert habe, dass es so aussieht, als wäre dieses Problem verschwunden. Vergessen Sie nicht, den Flavour-Teil durch Ihren aktuellen zu ersetzen.

gradlew installFlavorDebug
0
yuliskov