web-dev-qa-db-fra.com

Application trop grosse? Impossible d'exécuter dex: impossible de fusionner un nouvel index dans une instruction non jumbo

Je reçois le message d'erreur suivant lorsque je compile mon application:

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

Je suis au point que si je déclare une nouvelle méthode n'importe où dans mon package , je reçois cette erreur. Si je ne le fais pas, l'application compile.

J'aimerais savoir ce que cette erreur signifie exactement (et avec précision). Mon application est grosse, mais je ne pense pas que ce soit si grosse! Alors:

  • Est-ce que l'erreur signifie que j'ai trop de méthodes? Publique? statique? paquet? membres?
  • Est-ce lié aux méthodes/membres de mon paquet racine, ou aussi aux bibliothèques JAR incluses?
  • Est-il possible d'obtenir plus d'informations de débogage à ce sujet?

Je connais déjà le drapeau d'activation "jumbo" traité dans les questions similaires ici sous SO, cependant, je pense que le mode Jumbo n'est pas disponible au niveau de l'API que je cible (ICS).  

35
rupps

Cela est lié au nombre de méthodes de bibliothèques incluses dans le projet. Par exemple, si vous avez un suivi dans votre application, seulement Google Analytics utilise environ 7 000 méthodes . Un de mes projets utilisant Lombok (2 Mo de JAR) m'a posé le problème Résolu de se débarrasser de cette bibliothèque.

10

Pour construire gradle, il suffit d'ajouter les dexOptions dans build.gradle pour activer le mode Jumbo:

Android {
    dexOptions {
        jumboMode = true
    }
}

N'oubliez pas de lancer "gradle clean" avant votre nouveau bâtiment.

24
gary

Il semble que le problème se produise car tous les fichiers de classe de votre projet et les fichiers JAR sont regroupés avant DEXing. Cela n’est peut-être pas tout à fait vrai, mais il n’est pas facile de contrôler cela dans notre projet. Même en supprimant les éléments à l'origine de ce problème, le nettoyage et la reconstruction ne réglaient pas le problème de manière cohérente.

Nous avons donc saisi cette occasion pour passer notre projet à Android Studio et avons réussi à résoudre le problème en activant également ProGuard pour les versions de débogage. Plus précisément, nous n'utilisons que la phase de réduction de la chaîne de traitement de ProGuard.

Gradle facilite l’activation de ProGuard pour les versions de débogage:

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

Et voici la configuration de débogage ProGuard que nous utilisons:

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

Cela augmente le temps de construction du projet mais le bon côté est que le débogueur fonctionne toujours. 

La seule alternative plus rapide que je puisse imaginer est que tous les fichiers JAR sont supprimés manuellement des fichiers de classe inutilisés. Mais c’est non seulement difficile à faire, mais également gênant lorsque vous souhaitez utiliser ultérieurement une partie légèrement plus grande d’une bibliothèque.

J'espère que cela aide les autres développeurs aux prises avec ce problème. Et peut-être que dans l'avenir, Google pourra améliorer le compilateur qui effectue cette élagage par défaut. Notre fichier APK DEX est passé de 8 Mo à 2,9 Mo.

Nouvelles versions de gradle (1.0.0+)

Dans les versions plus récentes du studio Android (1.0+), Gradle fourni a été mis à jour. Certains changements ont été apportés au fonctionnement du mécanisme de génération afin que votre fichier Gradle de projet puisse désormais tirer parti des paramètres minifyEnabled et shrinkResources. La version actuelle est 1.1.0.

Suivre les changements sur une plate-forme en évolution rapide comme Android nécessite des efforts, mais cette dernière est souvent récompensée par de nouvelles fonctionnalités, de nouveaux outils et des temps de construction plus rapides. Mettre à jour Android Studio et (soigneusement) vos projets vaut donc le temps que vous investissez.

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

Quelques observations intéressantes. La même erreur peut apparaître si vous avez un projet multi-saveurs. C'est confu. En fait, j'ai tenté d'exécuter l'application avec la commande générique: gradlew installDebug. Quand j'ai changé la ligne de commande pour ressembler à ce problème est parti. N'oubliez pas de remplacer la pièce Flavour par votre pièce actuelle.

gradlew installFlavorDebug
0
yuliskov