Impossible d’exécuter dex: ID de méthode pas dans : 65536

J’ai déjà vu plusieurs versions des dex erros, mais celle-ci est nouvelle. clean / restart etc ne vous aidera pas. Les projets de bibliothèque semblent intacts et la dépendance semble être liée correctement.

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

ou

 Cannot merge new index 65950 into a non-jumbo instruction 

ou

 java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 

tl; dr : La solution officielle de Google est enfin arrivée!

http://developer.android.com/tools/building/multidex.html

Une seule petite astuce, vous devrez probablement le faire pour éviter de perdre de la mémoire lorsque vous effectuez un dex-ing.

 dexOptions { javaMaxHeapSize "4g" } 

Il existe également un mode jumbo qui peut résoudre ce problème de manière moins fiable:

 dexOptions { jumboMode true } 

Mise à jour: Si votre application est grosse et que vous avez trop de méthodes dans votre application principale, vous devrez peut-être réorganiser votre application selon

http://blog.osom.info/2014/12/too-many-methods-in-main-dex.html

Mise à jour 3 (11/3/2014)
Google a finalement publié une description officielle .


Mise à jour 2 (31/10/2014)
Le plugin Gradle v0.14.0 pour Android ajoute le support du multi-dex. Pour l’activer, il vous suffit de le déclarer dans build.gradle :

 android { defaultConfig { ... multiDexEnabled true } } 

Si votre application prend en charge Android avant la version 5.0 (c’est-à-dire si votre minSdkVersion est à 20 ou moins), vous devez également patcher dynamicment l’ application ClassLoader pour qu’elle puisse charger des classes à partir de dexes secondaires. Heureusement, il existe une bibliothèque qui fait cela pour vous. Ajoutez-le aux dépendances de votre application:

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

Vous devez appeler le code de correctif ClassLoader dès que possible. La documentation de la classe MultiDexApplication suggère trois façons de le faire (choisissez-en une , celle qui vous convient le mieux):

1 – Déclarez la classe MultiDexApplication comme application dans votre AndroidManifest.xml :

    ...   

2 – Demandez à votre classe d’ Application étendre la classe MultiDexApplication :

 public class MyApplication extends MultiDexApplication { .. } 

3 – Appelez MultiDex#install depuis votre méthode Application#attachBaseContext :

 public class MyApplication { protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); .... } .... } 

Mise à jour 1 (17/10/2014):
Comme prévu, le support multidex est fourni dans la révision 21 de la bibliothèque de support Android. Vous pouvez trouver le dossier android-support-multidex.jar dans le dossier / sdk / extras / android / support / multidex / library / libs.


Le support multi-dex résout ce problème. dx 1.8 permet déjà de générer plusieurs fichiers dex.
Android L prendra en charge la version multi-dex, et la prochaine révision de la bibliothèque de support couvrira les anciennes versions de l’API 4.

Il a été déclaré dans cet épisode de podcast Android Developers Backstage par Anwar Ghuloum. J’ai posté une transcription (et une explication générale multi-dex) de la partie concernée.

Comme déjà indiqué, vous avez trop de méthodes (plus de 65k) dans votre projet et vos bibliothèques.

Prévenir le problème: réduire le nombre de méthodes avec Play Services 6.5+ et support-v4 24.2+

Depuis souvent, les services Google Play sont l’un des principaux suspects de «gaspiller» les méthodes avec ses méthodes 20k + . Services Google Play version 6.5 ou ultérieure, vous pouvez inclure les services Google Play dans votre application en utilisant plusieurs bibliothèques client plus petites. Par exemple, si vous avez uniquement besoin de GCM et de cartes, vous pouvez choisir d’utiliser uniquement ces dépendances:

 dependencies { comstack 'com.google.android.gms:play-services-base:6.5.+' comstack 'com.google.android.gms:play-services-maps:6.5.+' } 

Vous trouverez la liste complète des sous-bibliothèques et leurs responsabilités dans le document officiel de Google .

Mise à jour : Depuis Support Library v4 v24.2.0, il a été divisé en modules suivants:

support-compat , support-core-utils , support-core-ui , support-media-compat et support-fragment

 dependencies { comstack 'com.android.support:support-fragment:24.2.+' } 

Notez cependant que si vous utilisez support-fragment , cela aura des dépendances sur tous les autres modules (par exemple, si vous utilisez android.support.v4.app.Fragment il n’y a aucun avantage)

Voir ici les notes de version officielles pour support-v4 lib


Activer MultiDexing

Depuis Lollipop (alias build tools 21+), il est très facile à manipuler. L’approche consiste à contourner les méthodes 65k par problème de fichier dex pour créer plusieurs fichiers dex pour votre application. Ajoutez ce qui suit à votre fichier de construction gradle ( extrait du document officiel de Google sur les applications comportant plus de 65 000 méthodes ):

 android { comstackSdkVersion 21 buildToolsVersion "21.1.0" defaultConfig { ... // Enabling multidex support. multiDexEnabled true } ... } dependencies { comstack 'com.android.support:multidex:1.0.1' } 

La deuxième étape consiste à préparer votre classe d’application ou, si vous ne l’ MultiDexApplication pas, à utiliser MultiDexApplication dans votre manifeste Android:

Soit append ceci à votre application.java

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

ou utiliser l’application fournie à partir de la bibliothèque mutlidex

    ...   

Empêcher OutOfMemory avec MultiDex

Comme autre conseil, si vous OutOfMemory exceptions OutOfMemory pendant la phase de construction, vous pouvez agrandir le tas avec

 android { ... dexOptions { javaMaxHeapSize "4g" } } 

ce qui définirait le tas à 4 gigaoctets.

Voir cette question pour plus de détails sur le problème de mémoire de tas de dex.


Analyser la source du problème

Pour parsingr la source des méthodes, le plugin gradle https://github.com/KeepSafe/dexcount-gradle-plugin peut vous aider en combinaison avec l’arbre de dépendance fourni par gradle avec par exemple

 .\gradlew app:dependencies 

Voir cette réponse et question pour plus d’informations sur le nombre de méthodes dans Android

Votre projet est trop grand. Vous avez trop de méthodes. Il ne peut y avoir que 65 536 méthodes par application. voir ici https://code.google.com/p/android/issues/detail?id=7147#c6

Le code ci-dessous aide, si vous utilisez Gradle. Vous permet de supprimer facilement les services Google inutiles (en supposant que vous les utilisiez) pour revenir en dessous du seuil de 65 000. Tous les crédits à cet article: https://gist.github.com/dmarcato/d7c91b94214acd936e42

Edit 2014-10-22 : Il y a eu beaucoup de discussions intéressantes sur l’essentiel référencé ci-dessus. TLDR? regardez celui-ci: https://gist.github.com/Takhion/10a37046b9e6d259bb31

Collez ce code au bas de votre fichier build.gradle et ajustez la liste des services Google dont vous n’avez pas besoin:

 def toCamelCase(Ssortingng ssortingng) { Ssortingng result = "" ssortingng.findAll("[^\\W]+") { Ssortingng word -> result += word.capitalize() } return result } afterEvaluate { project -> Configuration runtimeConfiguration = project.configurations.getByName('comstack') ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult // Forces resolve of configuration ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion Ssortingng prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library" File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir Task ssortingpPlayServices = project.tasks.create(name: 'ssortingpPlayServices', group: "Ssortingp") { inputs.files new File(playServiceRootFolder, "classes.jar") outputs.dir playServiceRootFolder description 'Ssortingp useless packages from Google Play Services library to avoid reaching dex limit' doLast { copy { from(file(new File(playServiceRootFolder, "classes.jar"))) into(file(playServiceRootFolder)) rename { fileName -> fileName = "classes_orig.jar" } } tasks.create(name: "ssortingpPlayServices" + module.version, type: Jar) { destinationDir = playServiceRootFolder archiveName = "classes.jar" from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) { exclude "com/google/ads/**" exclude "com/google/android/gms/analytics/**" exclude "com/google/android/gms/games/**" exclude "com/google/android/gms/plus/**" exclude "com/google/android/gms/drive/**" exclude "com/google/android/gms/ads/**" } }.execute() delete file(new File(playServiceRootFolder, "classes_orig.jar")) } } project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task -> task.dependsOn ssortingpPlayServices } } 

J’ai partagé un exemple de projet qui résout ce problème en utilisant le script de génération custom_rules.xml et quelques lignes de code.

Je l’ai utilisé sur mon propre projet et il fonctionne sans problème sur les appareils 1M + (d’Android-8 à la dernière version d’Android-19). J’espère que cela aide.

https://github.com/mmin18/Dex65536

Face au même problème et résolu en éditant mon fichier build.gradle sur la section dépendances, en supprimant:

 comstack 'com.google.android.gms:play-services:7.8.0' 

Et le remplacer par:

 comstack 'com.google.android.gms:play-services-location:7.8.0' comstack 'com.google.android.gms:play-services-analytics:7.8.0' 

Essayez d’append le code ci-dessous dans build.gradle, cela a fonctionné pour moi –

 comstackSdkVersion 23 buildToolsVersion '23.0.1' defaultConfig { multiDexEnabled true } 

La solution parfaite serait de travailler avec Proguard. comme aleb mentionné dans le commentaire. Cela diminuera la taille du fichier dex de moitié.

Vous pouvez parsingr un problème (références de fichier dex) en utilisant Android Studio:

Construire -> Analyser APK ..

Sur le panneau de résultats, cliquez sur le fichier classes.dex

Et vous verrez:

entrer la description de l'image ici

solution gradle + proguard:

 afterEvaluate { tasks.each { if (it.name.startsWith('proguard')) { it.getInJarFilters().each { filter -> if (filter && filter['filter']) { filter['filter'] = filter['filter'] + ',!.readme' + ',!META-INF/LICENSE' + ',!META-INF/LICENSE.txt' + ',!META-INF/NOTICE' + ',!META-INF/NOTICE.txt' + ',!com/google/android/gms/ads/**' + ',!com/google/android/gms/cast/**' + ',!com/google/android/gms/games/**' + ',!com/google/android/gms/drive/**' + ',!com/google/android/gms/wallet/**' + ',!com/google/android/gms/wearable/**' + ',!com/google/android/gms/plus/**' + ',!com/google/android/gms/topmanager/**' } } } } } 

Supprimez un fichier jar du dossier Libs et copiez-le dans un autre dossier, puis allez dans _Project Properties> Select Java Build Path, Select Libraries, sélectionnez Add External Jar, Select the Removed jar dans votre projet, cliquez sur save. Bibliothèque au lieu du dossier Libs. Maintenant, nettoyez et exécutez votre projet. Vous n’avez pas besoin d’append de code pour MultDex. Son simplement travaillé pour moi.

Je faisais face à la même question aujourd’hui, ce qui a fonctionné est en dessous de

Pour ANDROID STUDIO … Activer Instant Run

Dans Fichier-> Préférences-> Construire, exécuter, déployer-> Exécution instantanée-> Activer l’exécution instantanée pour le remplacement à chaud …

J’espère que cela aide