Не удалось выполнить идентификатор метода dex: не в [0, 0xffff]: 65536

Я видел разные версии dex erros раньше, но этот новый. clean/restart и т.д. не поможет. Библиотечные проекты кажутся неповрежденными, и зависимость, похоже, правильно связана.

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

или

Cannot merge new index 65950 into a non-jumbo instruction

или

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

tl; dr: официальное решение от Google наконец-то здесь!

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

Только один маленький наконечник, вам, вероятно, понадобится сделать это, чтобы предотвратить нехватку памяти при выполнении dex-ing.

dexOptions {
        javaMaxHeapSize "4g"
}

Там также есть jumbo-режим, который может исправить это менее надежным способом:

dexOptions {
        jumboMode true
}

Обновление. Если ваше приложение толще, и у вас слишком много методов внутри основного приложения, вам может потребоваться повторная организация вашего приложения в соответствии с

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

Ответ 1

Обновление 3 (11/3/2014)
Google наконец выпустил официальное описание.


Обновление 2 (10/31/2014)
Gradle плагин v0.14.0 для Android добавляет поддержку для multi-dex. Чтобы включить, вам просто нужно объявить его в файле build.gradle:

android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}

Если ваше приложение поддерживает Android до 5.0 (то есть, если ваш minSdkVersion равен 20 или ниже), вам также необходимо динамически исправлять приложение ClassLoader, чтобы он мог загружать классы из вторичных дексов. К счастью, есть library, который делает это для вас. Добавьте его в зависимости от приложения:

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

Вам нужно как можно скорее вызвать код патча ClassLoader. MultiDexApplication class предлагает три способа сделать это (выберите один из них, наиболее удобный для вас):

1 - Объявить класс MultiDexApplication в качестве приложения в вашем 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. Расширьте класс Application MultiDexApplication класс:

public class MyApplication extends MultiDexApplication { .. }

3 - Вызовите MultiDex#install из вашего метода Application#attachBaseContext:

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

Обновление 1 (10/17/2014):
Как и ожидалось, поддержка multidex поставляется в редакции 21 библиотеки поддержки Android. Вы можете найти папку android-support-multidex.jar в каталоге /sdk/extras/android/support/multidex/library/libs.


Поддержка Multi-Dex решает эту проблему. dx 1.8 уже позволяет создавать несколько файлов dex.
Android L будет поддерживать несколько делений изначально, а следующая версия библиотеки поддержки будет охватывать более старые версии обратно в API 4.

Это было указано в этом эпизоде ​​подкаста Android Developers Backstage от Anwar Ghuloum. Я разместил транскрипт (и общее объяснение с несколькими деками) соответствующей части.

Ответ 2

Как уже было сказано, у вас слишком много методов (более 65k) в вашем проекте и libs.

Предотвратите проблему: уменьшите количество методов в Play Services 6.5+ и support-v4 24.2 +

Так как часто службы Google Play являются одним из основных подозреваемых в методах "истощения" с помощью 20k + methods. Службы Google Play версии 6.5 или более поздней версии, вы можете включить Службы Google Play в своем приложении, используя несколько небольших клиентских библиотек. Например, если вам нужны только GCM и карты, вы можете использовать только эти зависимости:

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

Полный список суббиблиотек и его обязанности можно найти в официальном документе google.

Обновление. Поскольку Библиотека поддержки v4 v24.2.0 была разделена на следующие модули:

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

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

Однако обратите внимание, что если вы используете support-fragment, он будет иметь зависимости от всех других модулей (т.е. если вы используете android.support.v4.app.Fragment, нет никакой пользы)

См. здесь официальные заметки о выпуске для поддержки-v4 lib


Включить MultiDexing

Так как Lollipop (aka build tools 21+) очень прост в обращении. Подход состоит в том, чтобы обойти 65k-методы для каждой проблемы с файлом dex для создания нескольких файлов dex для вашего приложения. Добавьте в файл сборки gradle следующее: это взято из официального документа google для приложений с более чем 65k методами):

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

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

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

Второй шаг - либо подготовить свой класс приложения, либо если вы не используете приложение MultiDexApplication в вашем манифесте Android:

Либо добавьте это в свой Application.java

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

или используйте предоставленное приложение из mutlidex lib

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

Предотвращение OutOfMemory с помощью MultiDex

В качестве дополнительного совета, если вы столкнулись с OutOfMemory исключениями во время фазы сборки, вы можете увеличить кучу с помощью

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

который установил бы кучу до 4 гигабайт.

См. этот вопрос для получения более подробной информации о проблеме памяти кучи dex.


Проанализируйте источник проблемы

Для анализа источника методов плагин gradle https://github.com/KeepSafe/dexcount-gradle-plugin может помочь в сочетании с деревом зависимостей, предоставленным gradle с eg

.\gradlew app:dependencies

См. этот ответ и вопрос для получения дополнительной информации о количестве методов в android

Ответ 4

Приведенный ниже код помогает, если вы используете Gradle. Позволяет легко удалить ненужные сервисы Google (предполагая, что вы их используете), чтобы вернуться ниже порога 65k. Весь кредит на эту должность: https://gist.github.com/dmarcato/d7c91b94214acd936e42

Изменить 2014-10-22. Было много интересной дискуссии по тексту, приведенной выше. TL;DR? посмотрите на это: https://gist.github.com/Takhion/10a37046b9e6d259bb31

Вставьте этот код в нижней части файла build.gradle и настройте список служб google, которые вам не нужны:

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
    }
}

Ответ 5

Я поделился примером проекта, который решает эту проблему, используя custom_rules.xml build script и несколько строк кода.

Я использовал его в своем собственном проекте, и он работает безупречно на устройствах 1M + (от android-8 до последнего Android-19). Надеюсь, что это поможет.

https://github.com/mmin18/Dex65536

Ответ 6

Столкнувшись с той же проблемой и решив ее, отредактировав файл build.gradle в разделе зависимостей, удалив:

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

И заменив его на:

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

Ответ 7

Попробуйте добавить ниже код в build.gradle, это сработало для меня -

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    multiDexEnabled true
}

Ответ 8

Идеальное решение для этого было бы работать с Proguard. как говорится в комментарии. Это уменьшит размер файла dex наполовину.

Ответ 9

Вы можете анализировать проблему (ссылки на файлы dex) с помощью Android Studio:

Сборка → Анализ APK..

На панели результатов щелкните файл classes.dex

И вы увидите:

введите описание изображения здесь

Ответ 10

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/**'
            }
        }
    }
  }
}

Ответ 11

Удалите некоторые файлы jar из папки Libs и скопируйте в другую папку, и перейдите в _Project Properties > Выберите путь сборки Java, выберите библиотеки, выберите Добавить внешний баннер, выберите удаленный банку в свой проект, нажмите "Сохранить", это будет добавлено в папку "Связанная библиотека" вместо папки "Либы". Теперь очистите и запустите проект. Вам не нужно добавлять какой-либо код для MultDex. Он просто работал у меня.

Ответ 12

Сегодня я столкнулся с тем же вопросом, над чем работала ниже.

Для ANDROID STUDIO... Включить мгновенный запуск

В File- > Preferences- > Build, Execution, Deployment- > Instant Run- > Check Enable Instant run для горячей замены...

Надеюсь, что это поможет