Liczba odwołań do metod w pliku .dex nie może przekraczać 64k API 17


154

Buduję aplikację z biblioteką SugarORM, ale kiedy próbuję zbudować projekt dla API 17 (nie sprawdzałem innych), pokazuje błąd kompilacji.

    Information:Gradle tasks [:app:assembleDebug]
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72330Library UP-TO-DATE
:app:prepareComAndroidSupportCardviewV72330Library UP-TO-DATE
:app:prepareComAndroidSupportDesign2330Library UP-TO-DATE
:app:prepareComAndroidSupportMediarouterV72300Library UP-TO-DATE
:app:prepareComAndroidSupportRecyclerviewV72330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidVolleyVolley100Library UP-TO-DATE
:app:prepareComGithubSatyanSugar14Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServices840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAds840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAnalytics840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppindexing840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppinvite840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppstate840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAuth840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesBase840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesBasement840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesCast840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesDrive840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesFitness840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesGames840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesGcm840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesIdentity840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesLocation840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesMaps840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesMeasurement840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesNearby840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesPanorama840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesPlus840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesSafetynet840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesVision840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesWallet840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesWearable840Library UP-TO-DATE
:app:prepareMeDrakeetMaterialdialogLibrary131Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:compileDebugJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources
:app:prePackageMarkerForDebug
: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.8.0_51.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2
Information:BUILD FAILED
Information:Total time: 21.663 secs
Information:2 errors
Information:0 warnings
Information:See complete output in console

Ale kiedy buduję ten projekt dla Androida w wersji 5.0 lub nowszej, działa dobrze. Jeśli usunę zależność gradle od SugarORM, będzie działać dobrze na obu urządzeniach w wersji 4.2.2 i 5.0.



spróbuj użyć proguard ten link android-arsenal.com/details/1/337 określa używanie SugarORM z proguard
Shaan_B

19
Właśnie to otrzymałem po uaktualnieniu do api 23. Po prostu niemożliwe jest produktywność z Androidem. Każdy sdk coś psuje. Każda aktualizacja AS psuje rzeczy. Komunikaty o błędach są bezużyteczne. JAK Zepsuty. Śmieci, śmieci, śmieci.
RunLoop,

1
@RunLoop nie trać nadziei .... Odkryłem, że Android jest najlepszą platformą, jaką kiedykolwiek stworzono .... Moch Elastyczny i potężny .... Ponieważ zabrudzisz sobie ręce podczas kodowania ... Będzie dobrze .... Każdy komunikat o błędzie jest przydatny. Ale trzeba zrozumieć wiadomości
Sandeep Singh Rana

2
@Balaj Khan One or more of the answers is exemplary and worthy of an additional bounty.Just to the point and accurate answer.Proponuję najlepszą (i zaakceptowaną) odpowiedź!
Jon Goodwin

Odpowiedzi:


331

Masz zbyt wiele metod. Metody dex mogą być tylko 65536 .

Jak sugerowano, możesz skorzystać z obsługi multidex .

Po prostu dodaj te wiersze w module/build.gradle:

android {

    defaultConfig {
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  implementation 'com.android.support:multidex:1.0.3'  //with support libraries
  //implementation 'androidx.multidex:multidex:2.0.1'  //with androidx libraries
}

Również w twojej Manifestdodać MultiDexApplicationklasę z multidex biblioteki wsparcia z elementem podającym

    <?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">

            <!-- If you are using androidx use android:name="androidx.multidex.MultiDexApplication" -->

            <!--If you are using your own custom Application class then extend -->
            <!--MultiDexApplication and change above line as-->
            <!--android:name=".YourCustomApplicationClass"> -->

            ...
        </application>
    </manifest>

Jeśli używasz własnej Applicationklasy, zmień klasę nadrzędną z Applicationna MultiDexApplication.
Jeśli nie możesz tego zrobić, w swojej klasie Application zastąp attachBaseContextmetodę:

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

Innym rozwiązaniem jest próba usunięcia nieużywanego kodu za pomocą ProGuard - Skonfiguruj ustawienia ProGuard dla swojej aplikacji, aby uruchomić ProGuard i upewnij się, że włączono zmniejszanie dla kompilacji wydań.


1
@Override protected void attachBaseContext (Context newBase) {super.attachBaseContext (newBase); MultiDex.install (this); } również zastąpić
Sandeep Singh Rana

1
Klikając przycisk Cmd MultiDexApplication, widzę, że zdekompilowany plik .class już wykonuje dokładnie takie przesłonięcie attachBaseContext (), które opisujesz. Więc myślę, że nie będzie trzeba tego ponownie przesłonić ...
Mete,

4
Co jeśli nie mam zbyt wielu metod. Nie mam zbyt wielu metod w mojej aplikacji. Uważam, że nawet tego nie osiąga.
Neon Warge,

6
Zrobiłem tylko te dwie części: „multiDexEnabled true” i skompilowałem „com.android.support:multidex:1.0.0” w moim pliku build.grandle. Nie musiałem niczego zmieniać w moim pliku manifestu ani robić innych rzeczy, o których wspomniałeś, dotyczących zastępowania attachBaseContext, itp. Ale Twoje rozwiązanie rozwiązało problem! Dzięki.
Jaime Montoya

2
@NeonWarge Prawdopodobnie z powodu twoich zależności. Być może włączyłeś wszystkie usługi Google Play? Sprawdź tę odpowiedź, aby poznać szczegóły
mr5

132

W android / app / build.gradle

android {

compileSdkVersion 23

 buildToolsVersion '23.0.0'

    defaultConfig {
        applicationId "com.dkm.example"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

Umieść to w swoim defaultConfig:

multiDexEnabled true 

mi to pasuje


3
To jest tylko dla Lollipopa lub nowszego, prawda?
Vic Torious

1
To sprawia, że ​​kompilacja jest udana, ale aplikacja ulega awarii po uruchomieniu.
Vasanth

18

Otrzymałem ten komunikat o błędzie, ponieważ podczas kodowania wersji kompilacji automatycznej aktualizacji projektu w moim build.gradlepliku:

android {
    ...
    buildToolsVersion "23.0.2"
    ...
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:design:23.4.0' }

Rozwiąż to, poprawiając wersję:

android {
        ...
        buildToolsVersion "23.0.2"
        ...
    }

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'
}

2
Tworzę prostą aplikację, która działała dobrze, dopóki nie spróbowałem postępować zgodnie z samouczkiem Google Map Objects. Nagle nie mogłem już skompilować. To rozwiązanie rozwiązało problem. Jak do diabła to rozpracowałeś?
maccaroo

4
Ta metoda na szczęście zadziałała, ponieważ nowe biblioteki kompilacyjne mają zbyt wiele metod (przekracza 65536), a stare nie. Więc to tylko szybka naprawa, wcześniej czy później powinieneś to naprawić, dodając obsługę multidex, taką jak zaakceptowana odpowiedź.
Quan Nguyen

15

Oto, co zadziałało dla mnie:

Dzieje się tak, ponieważ istnieje zbyt wiele nieużywanych metod. Większość z tych metod pochodzi z bibliotek dołączonych do pliku build.gradle

Użyj zmniejszania i zmniejszania zasobów, aby rozwiązać ten problem za pomocą gradle i jednocześnie wyczyścić kod.

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

12

Zmień build.gradle na poziomie aplikacji:

android {

compileSdkVersion 23

 buildToolsVersion '23.0.0'

    defaultConfig {
        applicationId "com.dkm.example"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

to działało dla mnie.


tak, to stary problem, ale dla ostatnich wersji API potrzebujemy tylko multiDexEnabledopcji, bez zależności i zmian w pliku manifestu
Hpsaturn

11

Ten błąd może również wystąpić, gdy ładujesz wszystkie API usług Google Play, gdy używasz tylko kilku.

Jak stwierdził Google: „W wersjach usług Google Play wcześniejszych niż 6.5 trzeba było skompilować cały pakiet interfejsów API w swojej aplikacji. W niektórych przypadkach utrudniało to utrzymanie liczby metod w aplikacji (w tym Framework API, metody biblioteczne i własny kod) w ramach limitu 65 536.

Od wersji 6.5 możesz zamiast tego selektywnie kompilować interfejsy API usług Google Play w swojej aplikacji ”.

Na przykład, gdy Twoja aplikacja wymaga map-usług-odtwarzania, lokalizacji-usług-odtwarzania, musisz dodać tylko dwa pliki apis w pliku build.gradle na poziomie aplikacji, jak pokazano poniżej:

compile 'com.google.android.gms:play-services-maps:10.2.1'
compile 'com.google.android.gms:play-services-location:10.2.1'

Zamiast:

compile 'com.google.android.gms:play-services:10.2.1'

Aby uzyskać pełną dokumentację i listę apis usług Google Play, kliknij tutaj


9

Gdy odwołania do aplikacji przekraczają 65 536 metod, występuje błąd kompilacji wskazujący, że aplikacja osiągnęła limit architektury kompilacji systemu Android

Obsługa Multidex przed Androidem 5.0

Wersje platformy wcześniejsze niż Android 5.0 (poziom API 21) używają środowiska wykonawczego Dalvik do wykonywania kodu aplikacji. Domyślnie Dalvik ogranicza aplikacje do jednego pliku z kodem bajtowym classes.dex na plik APK. Aby obejść to ograniczenie, możesz dodać do swojego projektu bibliotekę obsługi multidex:

dependencies {
  implementation 'com.android.support:multidex:1.0.3'
}

Obsługa Multidex dla Androida 5.0 i nowszych

Android 5.0 (poziom API 21) i nowszy używa środowiska uruchomieniowego o nazwie ART, które natywnie obsługuje ładowanie wielu plików DEX z plików APK. Dlatego jeśli twoja minSdkVersion ma 21 lub wyższą wersję, nie potrzebujesz multidex biblioteki obsługującej .

Unikaj limitu 64 KB

  • Usuń nieużywany kod za pomocą ProGuard - Włącz zmniejszanie kodu

Skonfiguruj multidex w aplikacji dla

Jeśli twoja minSdkVersion jest ustawiona na 21 lub wyższą, wszystko, co musisz zrobić, to ustawić multiDexEnabled na true w pliku build.gradle na poziomie modułu

android {
defaultConfig {
    ...
    minSdkVersion 21 
    targetSdkVersion 28
    multiDexEnabled true
  }
 ...
}

jeśli twoja minSdkVersion jest ustawiona na 20 lub mniej, musisz użyć biblioteki obsługującej multidex

android {
defaultConfig {
    ...
    minSdkVersion 15 
    targetSdkVersion 28
    multiDexEnabled true
   }
   ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.3'
}

Zastąp klasę Application, zmień ją, aby rozszerzyć MultiDexApplication (jeśli to możliwe) w następujący sposób:

public class MyApplication extends MultiDexApplication { ... }

dodać do pliku manifestu

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
            android:name="MyApplication" >
        ...
    </application>
</manifest>

8

Miałem do czynienia z tym samym problemem i aby uzyskać obsługę multidex, musisz pamiętać o minSdkVersion swojej aplikacji. Jeśli używasz minSdkVersion 21 lub nowszej, po prostu napisz multiDexEnabled true w ten sposób

defaultConfig {
    applicationId *******************
    minSdkVersion 21
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
}

U mnie działa i jeśli używasz minSdkVersion poniżej 21 (poniżej Lolipopa ), musisz zrobić dwie dodatkowe proste rzeczy

1. Najpierw dodaj tę zależność

kompiluj „com.android.support:multidex:1.0.1”

w pliku build.gradle.

2. Na koniec dodaj jeden poniższy wiersz do swojej aplikacji w manifeście

android: name = "android.support.multidex.MultiDexApplication"

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:name="android.support.multidex.MultiDexApplication"
    android:theme="@style/AppTheme" >
    <activity android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Bingo wtedy będzie działać również w niższej wersji .. :) Miłego kodowania


1

Na marginesie, przed dodaniem obsługi multidex - upewnij się, że nie dodajesz niepotrzebnych zależności.

Na przykład w oficjalnym przewodniku po analityce na Facebooku

Wyraźnie stwierdzają, że należy dodać następującą zależność:

implementation 'com.facebook.android:facebook-android-sdk:[4,5)'

czyli właściwie cały FacebookSDK - więc jeśli potrzebujesz na przykład tylko Analytics, musisz go zastąpić:

implementation 'com.facebook.android:facebook-core:5.+'

Opcje częściowego zestawu SDK dla Facebooka


Kompletnie się zgadzam. Na przykład w moim przypadku potrzebowałem tylko przycisku „zaloguj się przez Facebooka” i korzystałem z całego zestawu sdk na Facebooku. Zastąpiłem go facebook-corei facebook-logini błąd zniknął.
cleybertandre

0

Uaktualnienie Gradle działa dla mnie. Poszukaj aktualizacji w witrynie Android, a następnie dodaj ją do pliku build.gradle (projekt) w ten sposób

 dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-alpha4'   
          ....
    }

następnie zsynchronizuj projekt z plikiem gradle plus może się to zdarzyć czasami z powodu java.exe (w moim przypadku) po prostu wymuś zabicie java.exe z menedżera zadań w systemie Windows, a następnie ponownie uruchom program


0

Możesz też spróbować tego:

android{
    .
    .
    // to avoid DexIndexOverflowException
    dexOptions {
       jumboMode true
    }
}

Mam nadzieję, że to komuś pomoże. Dzięki


0

**

Dla twórców gier Unity

**

Jeśli ktoś przychodzi tutaj, ponieważ ten błąd pojawił się w jego projekcie Unity, przejdź do Plik-> Ustawienia kompilacji -> Ustawienia odtwarzacza -> Odtwarzacz. przejdź do Ustawień publikowania i na karcie Kompilacja włącz „Niestandardowy szablon Gradle Launchera”. ścieżka zostanie wyświetlona pod tym tekstem. przejdź do ścieżki i dodaj multiDexEnabled true w ten sposób:

defaultConfig {
    minSdkVersion **MINSDKVERSION**
    targetSdkVersion **TARGETSDKVERSION**
    applicationId '**APPLICATIONID**'
    ndk {
        abiFilters **ABIFILTERS**
    }
    versionCode **VERSIONCODE**
    versionName '**VERSIONNAME**'
    multiDexEnabled true
}

-1

możesz włączyć „Natychmiastowe uruchamianie” w Android Studio, aby uzyskać obsługę multidex.


-2

Zrób to, to działa:

defaultConfig {
    applicationId "com.example.maps"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
}

2
Proszę wyjaśnij swoją odpowiedź. Odpowiedzi zawierające tylko kod są odradzane na SO. Dziękuję Ci.
Gennadii Saprykin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.