J'ai déjà vu diverses versions des erreurs dex, mais celle-ci est nouvelle. nettoyer/redémarrer, etc. ne vous aidera pas. Les projets de bibliothèque semblent intacts et les dépendances semblent être correctement liées.
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 petite astuce, vous aurez probablement besoin de le faire pour éviter le manque de mémoire lorsque vous effectuez dux-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 grasse et que vous avez trop de méthodes dans votre application principale, vous devrez peut-être réorganiser votre application selon les instructions.
http://blog.osom.info/2014/12/too-many-methods-in-main-dex.html
Mise à jour 3 (11/3/2014)
Google a finalement publié description officielle .
Mise à jour 2 (31/10/2014)
Gradle plugin v0.14.0 pour Android ajoute le support pour multi-dex. Pour l'activer, il suffit de le déclarer dans build.gradle :
Android {
defaultConfig {
...
multiDexEnabled true
}
}
Si votre application prend en charge Android avant 5.0 (c'est-à-dire si votre minSdkVersion
vaut 20 ou moins), vous devez également appliquer un correctif dynamique à l'application ClassLoader , il pourra donc charger des classes à partir dex secondaires. Heureusement, il existe une bibliothèque qui le fait pour vous. Ajoutez-le aux dépendances de votre application:
dependencies {
...
compile 'com.Android.support:multidex:1.0.0'
}
Vous devez appeler le code de correctif ClassLoader dès que possible. MultiDexApplication
la classe documentation suggère trois façons de le faire (choisissez l'une d'elles , celle qui vous convient le mieux ):
1 - Déclarez MultiDexApplication
class comme application dans votre AndroidManifest.xml :
<?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>
2 - Votre classe Application
est-elle étendue MultiDexApplication classe:
public class MyApplication extends MultiDexApplication { .. }
3 - Appelez MultiDex#install
à partir de 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, support multidex est fourni avec la révision 21 de Android Bibliothèque de support. Vous pouvez trouver le fichier 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 multi-dex de manière native, et la prochaine révision de la bibliothèque de support couvrira les versions plus anciennes de l’API 4.
Il a été déclaré dans this Android Les développeurs ont réalisé un épisode de podcast par Anwar Ghuloum. J'ai posté une transcription (et une explication générale multi-dex) de la partie pertinente.
Comme déjà indiqué, vous avez trop de méthodes (plus de 65k) dans votre projet et vos bibliothèques.
Depuis souvent les services de Google Play sont l’un des principaux suspects dans les méthodes de "gaspillage" avec ses méthodes 20k + . Les services Google Play, version 6.5 ou ultérieure, vous permettent d'inclure les services Google Play de votre application utilisent un certain nombre de bibliothèques clientes plus petites. Par exemple, si vous avez uniquement besoin de MCG et de cartes, vous pouvez choisir de: utilisez ces dépendances uniquement:
dependencies {
compile 'com.google.Android.gms:play-services-base:6.5.+'
compile 'com.google.Android.gms:play-services-maps:6.5.+'
}
Mise à jour : Depuis Support Library v4 v24.2.0, il a été divisé en modules:
support-compat
,support-core-utils
,support-core-ui
,support-media-compat
etsupport-fragment
dependencies {
compile 'com.Android.support:support-fragment:24.2.+'
}
Notez cependant que si vous utilisez support-fragment
, il aura des dépendances par rapport à tous les autres modules (c.-à-d. Si vous utilisez Android.support.v4.app.Fragment
il n'y a aucun avantage)
Voir ici les notes de version officielles de support-v4 lib
Depuis Lollipop (aka build tools 21+), il est très facile à manipuler. L'approche consiste à contourner le problème des méthodes 65k par fichier dex pour créer plusieurs fichiers dex pour votre application. Ajoutez les éléments suivants à votre fichier de construction Gradle ( extrait du document officiel Google concernant les applications comportant plus de 65 000 méthodes ):
Android {
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.Android.support:multidex:1.0.1'
}
La deuxième étape consiste à préparer votre classe d’application ou, si vous n’étendez pas Application, à utiliser le MultiDexApplication
de votre manifeste Android:
Ajoutez-le à votre application.Java
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
ou utilisez l'application fournie à partir de la bibliothèque mutlidex
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.example.Android.myapplication">
<application
...
Android:name="Android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
Comme autre astuce, si vous rencontrez des exceptions OutOfMemory
au cours de 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 dex.
Pour analyser la source des méthodes, le plugin Gradle https://github.com/KeepSafe/dexcount-gradle-plugin peut aider à combiner l’arbre de dépendance fourni par gradle avec, par exemple.
.\gradlew app:dependencies
Voir cette réponse et cette question pour plus d'informations sur le nombre de méthodes dans Android
Votre projet est trop gros. 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 $. Tout crédit à ce message: https://Gist.github.com/dmarcato/d7c91b94214acd936e42
Edit 2014-10-22 : Il y a eu beaucoup de discussions intéressantes sur le Gist mentionné 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(String string) {
String result = ""
string.findAll("[^\\W]+") { String Word ->
result += Word.capitalize()
}
return result
}
afterEvaluate { project ->
Configuration runtimeConfiguration = project.configurations.getByName('compile')
ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult
// Forces resolve of configuration
ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion
String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library"
File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir
Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") {
inputs.files new File(playServiceRootFolder, "classes.jar")
outputs.dir playServiceRootFolder
description 'Strip 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: "stripPlayServices" + 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 stripPlayServices
}
}
Face au même problème et résolu en modifiant mon fichier build.gradle dans la section dependencies, en supprimant:
compile 'com.google.Android.gms:play-services:7.8.0'
Et en le remplaçant par:
compile 'com.google.Android.gms:play-services-location:7.8.0'
compile 'com.google.Android.gms:play-services-analytics:7.8.0'
J'ai partagé un exemple de projet qui résout ce problème à l'aide du script de génération custom_rules.xml et de quelques lignes de code.
Je l'ai utilisé sur mon propre projet et il fonctionne parfaitement sur les appareils 1M + (d'Android-8 au dernier Android-19). J'espère que ça aide.
Essayez d'ajouter le code ci-dessous dans build.gradle, cela a fonctionné pour moi -
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
multiDexEnabled true
}
La solution idéale pour cela serait de travailler avec Proguard. comme aleb mentionné dans le commentaire. Cela réduira de moitié la taille du fichier dex.
Supprimez un fichier jar du dossier Libs et copiez-le dans un autre dossier. Accédez ensuite à Propriétés du projet> Sélectionnez Java chemin de construction, sélectionnez bibliothèques, sélectionnez Ajouter un fichier jar externe, sélectionnez le fichier jar supprimé de votre projet, cliquez sur Enregistrer. être ajouté sous Bibliothèque référencée au lieu du dossier Libs. Maintenant, nettoyez et lancez votre projet. Vous n'avez pas besoin d'ajouter de code Any pour MultDex. Cela a tout simplement fonctionné pour moi.
Je faisais face au même problème aujourd'hui, ce qui a fonctionné est en bas
Pour Android STUDIO ... Activer l'exécution instantanée
Dans Fichier-> Préférences-> Génération, Exécution, Déploiement-> Exécution instantanée-> Vérifier Activer l'exécution instantanée pour le remplacement à chaud ...
J'espère que ça aide
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/**'
}
}
}
}
}