web-dev-qa-db-de.com

Bei älteren APIs wurde ein Grenzwert von 64 KB überschritten, jedoch nicht neuer

Ich wundere mich daher, warum ich auf das 64-k-Dex-Methodenlimit stoße, wenn ich versuche, meine App auf Android-Versionen auszuführen, die älter als Lollipop sind, wenn es bei den neueren Versionen einwandfrei läuft. 

Könnte es sein, weil die Unterstützungsbibliotheken tatsächlich referenziert werden, wenn sie auf älteren Versionen ausgeführt werden?

Das ist mein gradle: 

    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:[email protected]') {
        transitive = true
    }
}

BEARBEITEN:

Um dies zu klären: Dies geschieht, wenn ich versuche, die App auf einem Emulator auszuführen, auf dem z. KitKat API 19

Crash-Protokolle von der Gradle-Konsole:

...
: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

Crash-Nachricht aus dem Message-Fenster:

: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

Um Ihre spezifische Frage zu beantworten, lautet:

  • Diese Beschränkung der Methodenanzahl gilt für die DEX-Datei (Dalvik Executable).
  • Eine häufige Problemumgehung für diese Einschränkung besteht darin, mehrere DEX-Dateien zu haben.
  • Ältere Versionen von Android unterstützen nicht automatisch mehrere DEX-Dateien.
  • Ab Lollipop unterstützt das System es nativ.

Deshalb schlägt es auf älteren Geräten fehl, funktioniert aber auf neueren Geräten. Es hat nichts mit Unterstützungsbibliotheken zu tun.

So fügen Sie meiner Antwort weitere nützliche Inhalte hinzu:

Vielleicht möchten einige jedoch wissen, wie Sie dieses Problem auf älteren Geräten umgehen können. Beachten Sie, dass ich das Wort natively in meinen Aufzählungspunkten oben verwendet habe. Das bedeutet, dass es Workarounds gibt, die ältere Plattformen unterstützen, aber Sie müssen diese Workarounds in Ihre App codieren.

Die Problemumgehung (und sogar das Problem selbst) wird in diesem Google-Handbuch ausführlich erläutert: http://developer.Android.com/tools/building/multidex.html

Die Basis davon ist:

  • füge multidex zu deinen Abhängigkeiten hinzu compile 'com.Android.support:multidex:+'
  • aktiviere multiDex in deinem Build-Skript in Android-> default config multiDexEnabled true
  • auf dem Manifest machen Sie Ihre Anwendung von MultidexApplicationAndroid:name="Android.support.multidex.MultiDexApplication" oder, wenn Sie Application für Ihre eigene App unterlegen müssen, machen Sie Ihre Anwendung davon.
34
Budius

Das Problem tritt bei der Verwendung von Instant Run- und Pre-Lollipop-Geräten auf!

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

2
Boy

Stimme @Budius vollständig zu. Sie müssen eine Anwendungsklasse im Manifest angeben. Und lassen Sie Ihre Anwendungsklasse MultiDexApplication erweitern.

Es ist noch eine Sache nötig. Aufrufen des Attach-Basiskontexts in Ihrer MultiDexApplication-Klasse

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

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

Dies funktionierte gut für Pre- und Post-Lollipop-Geräte.

2
drulabs

sie sollten multiDexEnabled = true in Ihrer defaultConfig in der Gradle-Datei hinzufügen.