web-dev-qa-db-fra.com

Limite de 64 Ko dépassée sur les anciennes API que Lollipop, mais pas plus récente

Je me demande donc pourquoi la limite de la méthode dex de 64k est rencontrée lorsque j'essaie d'exécuter mon application sur des versions d'Android antérieures à Lollipop, alors qu'elle fonctionne parfaitement sur les versions plus récentes. 

Serait-ce possible, car les bibliothèques de support sont réellement référencées lors de l'exécution sur les versions antérieures?

Ceci est mon grade: 

    apply plugin: 'com.Android.application'

    Android {
        compileSdkVersion 23
        buildToolsVersion '23.0.2'
    lintOptions {
        checkReleaseBuilds true
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }

    defaultConfig {
        applicationId "com.domain.myapp"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 27
        versionName "1.2"

        // Vector compat
        vectorDrawables.useSupportLibrary = true 
    }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

dependencies {

    compile files('libs/commons-io-2.4.jar')
    compile files('libs/activation.jar')
    compile files('libs/additionnal.jar')
    compile files('libs/mail.jar')
    compile project(':libraries:preferencefragment')

    // Gmail API
    compile('com.google.api-client:google-api-client-Android:1.20.0') {
        exclude group: 'org.Apache.httpcomponents'
    }
    compile('com.google.apis:google-api-services-gmail:v1-rev29-1.20.0') {
        exclude group: 'org.Apache.httpcomponents'
    }

    // Play Services
    compile 'com.google.Android.gms:play-services-location:8.4.0'
    compile 'com.google.Android.gms:play-services-maps:8.4.0'
    compile 'com.google.Android.gms:play-services-ads:8.4.0'
    compile 'com.google.Android.gms:play-services-analytics:8.4.0'
    compile 'com.google.Android.gms:play-services-identity:8.4.0'

    // Support libraries
    compile 'com.Android.support:support-v4:23.3.0'
    compile 'com.Android.support:appcompat-v7:23.3.0'
    compile 'com.Android.support:cardview-v7:23.3.0'
    compile 'com.Android.support:design:23.3.0'

    compile 'com.github.bumptech.glide:glide:3.6.1'
    compile 'com.anjlab.Android.iab.v3:library:1.0.20'
    compile 'com.sothree.slidinguppanel:library:2.0.3'
    compile 'com.commit451:PhotoView:1.2.5'

    compile('com.github.afollestad.material-dialogs:core:0.8.5.7@aar') {
        transitive = true
    }
}

MODIFIER:

Pour clarifier: cela se produit lorsque j'essaie d'exécuter l'application sur un émulateur exécuté, par exemple. API KitKat 19

Crash logs depuis la console Gradle:

...
:App:generateDebugInstantRunAppInfo
:App:transformClassesWithDexForDebug
AGPBI: {"kind":"error","text":"The number of method references in a .dex file cannot exceed 64K.\nLearn how to resolve this issue at https://developer.Android.com/tools/building/multidex.html","sources":[{}],"original":"UNEXPECTED TOP-LEVEL EXCEPTION:\ncom.Android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536\n\tat com.Android.dx.merge.DexMerger$6.updateIndex(DexMerger.Java:484)\n\tat com.Android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.Java:261)\n\tat com.Android.dx.merge.DexMerger.mergeMethodIds(DexMerger.Java:473)\n\tat com.Android.dx.merge.DexMerger.mergeDexes(DexMerger.Java:161)\n\tat com.Android.dx.merge.DexMerger.merge(DexMerger.Java:188)\n\tat com.Android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.Java:504)\n\tat com.Android.dx.command.dexer.Main.runMonoDex(Main.Java:334)\n\tat com.Android.dx.command.dexer.Main.run(Main.Java:277)\n\tat com.Android.dx.command.dexer.Main.main(Main.Java:245)\n\tat com.Android.dx.command.Main.main(Main.Java:106)\n","tool":"Dex"}

 FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':App:transformClassesWithDexForDebug'.
> com.Android.build.api.transform.TransformException: com.Android.ide.common.process.ProcessException: Java.util.concurrent.ExecutionException: com.Android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/Java'' finished with non-zero exit value 2

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Message d'erreur depuis la fenêtre de message:

:App:transformClassesWithDexForDebug
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.Android.com/tools/building/multidex.html
Error:Execution failed for task ':App:transformClassesWithDexForDebug'.
> com.Android.build.api.transform.TransformException: com.Android.ide.common.process.ProcessException: Java.util.concurrent.ExecutionException: com.Android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/Java'' finished with non-zero exit value 2
19
Jakob

Répondre à votre question spécifique est:

  • Cette limitation du nombre de méthodes concerne le fichier DEX (Dalvik Executable).
  • Une solution de contournement courante pour cette limitation consiste à avoir plusieurs fichiers DEX.
  • Les anciennes versions d’Android ne prennent pas nativement en charge plusieurs fichiers DEX.
  • À partir de Lollipop, le système le prend en charge de manière native.

C'est pourquoi il échoue sur les anciens appareils mais fonctionne sur les nouveaux. Cela n'a rien à voir avec les bibliothèques de support.

Pour ajouter plus de contenu utile à la réponse:

Mais peut-être que certains voudront peut-être savoir comment résoudre ce problème sur des appareils plus anciens, veuillez noter que j'ai utilisé Word natively sur les points ci-dessus. Cela signifie qu'il existe des solutions de contournement pour que les anciennes plates-formes le prennent en charge, mais vous devez les coder dans votre application.

La solution de contournement (et même le problème lui-même) est détaillée dans ce guide Google: http://developer.Android.com/tools/building/multidex.html

La base de celui-ci est:

  • ajoutez multidex à vos dépendances compile 'com.Android.support:multidex:+'
  • activez multiDex sur votre script de construction sous Android-> configuration par défaut multiDexEnabled true
  • sur le manifeste, votre application s'étend de MultidexApplicationAndroid:name="Android.support.multidex.MultiDexApplication" ou, si vous avez besoin de sous-classe Application pour votre propre application, en étendez l'application à partir de celle-ci.
34
Budius

Le problème se produit lorsque vous utilisez des appareils Instant Run et pré-Lollipop!

https://code.google.com/p/Android/issues/detail?id=208577https://code.google.com/p/Android/issues/detail?id= 196809

2
Boy

Tout à fait d’accord avec @Budius. Vous devez mentionner une classe d'application dans le manifeste. Et demandez à votre classe d'application d'étendre MultiDexApplication.

Il y a encore une chose à faire. Appel du contexte de base attaché dans votre classe MultiDexApplication

public class MyApplicationClass extends MultiDexApplication... {
....

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

Cela a bien fonctionné pour moi sur les appareils pré et post Lollipop.

2
drulabs

vous devriez ajouter multiDexEnabled = true in à votre defaultConfig dans le fichier Gradle.