Слишком большое приложение? Невозможно выполнить dex: невозможно объединить новый индекс в инструкцию без jumbo
При компиляции приложения появляется следующее сообщение:
[2014-05-07 21:48:42 - Dex Loader] Unable to execute dex: Cannot merge new index 65536 into a non-jumbo instruction!
Я нахожусь в точке, что , если я объявляю новый метод в любом месте моего пакета, я получаю эту ошибку. Если я этого не сделаю, приложение будет компилироваться.
Я хотел бы знать, что именно (и точно) означает эту ошибку. Мое приложение большое, но я не думаю, что он такой большой! Итак:
- Означает ли ошибка, что у меня слишком много методов? общественности? статические? пакет? Члены?
- Связано ли это с методами/членами моего корневого пакета или с включенными библиотеками JAR?
- Есть ли способ получить больше отладочной информации об этом?
Я уже знаю о том, что флаг "jumbo" включен в похожие вопросы здесь, в SO, однако, я думаю, что jumbo-режим недоступен на уровне API, на который я нацелен (ICS).
Ответы
Ответ 1
Это связано с количеством методов библиотек, включенных в проект. Например, если у вас есть отслеживание в вашем приложении, просто Google Analytics составляет ~ 7000 методов.
В одном из моих проектов с использованием Ломбока (2 МБ JAR) мне дали эту проблему. Решил избавиться от этой библиотеки.
Ответ 2
Ваша ошибка связана с количеством строк (методов, членов и т.д.) в одном файле dex.
Вам нужно скомпилировать приложение, используя jumbo in dex, с помощью:
dex.force.jumbo=true
in project.properties
Это увеличивает предел для строк в файлах dex. И ваш проект, вероятно, скомпилируется.
Также с помощью jumbo set другой предел 64K только для методов в одном dex. Если вы получите этот предел в будущем, вам нужно будет удалить некоторые зависимости.
UPDATE: для сборки с Gradle:
В Gradle вы можете включить jumboMode также в файле build.gradle с помощью:
dexOptions {
jumboMode = true
}
Check:
Android Build: Dex Jumbo Mode в Gradle
Также с помощью Gradle вы можете избежать ограничения 64K для методов с помощью сборки multidex, здесь:
https://developer.android.com/tools/building/multidex.html
Ответ 3
Для сборки gradle просто добавьте dexOptions в build.gradle, чтобы включить jumbo-режим:
android {
dexOptions {
jumboMode = true
}
}
Не забудьте запустить "gradle clean" перед новым зданием.
Ответ 4
Похоже, проблема возникает из-за того, что все файлы классов из вашего проекта и файлы JAR упакованы вместе перед DEXING. Это может быть не совсем верно, но любой способ контролировать это в нашем проекте оказался довольно сложным. Даже удаление материалов, которые изначально вызвали эту проблему, очистка и восстановление, не помогли нам решить проблему.
Итак, мы воспользовались этой возможностью, чтобы переключить наш проект на Android Studio и смогли решить проблему, включив ProGuard для отладочных сборников. Точнее, мы используем только термоусадочную фазу цепи обработки ProGuard.
Gradle упрощает включение ProGuard для отладочных сборников:
buildTypes {
debug {
runProguard true
proguardFile 'proguard-project-debug.txt'
}
}
И вот конфигурация Debug ProGuard, которую мы используем:
-keep class com.your.code.**
# Use -keep to explicitly keep any other classes shrinking would remove
-dontoptimize
-dontobfuscate
-ignorewarnings
Это увеличивает время сборки проекта, но хорошая сторона заключается в том, что отладчик все еще работает.
Единственной более быстрой альтернативой, о которой я могу думать, является то, что любые файлы JAR вручную удаляются из неиспользуемых файлов классов. Но это не только сложно сделать, но и неудобно, когда вы захотите использовать немного большую часть библиотеки в более позднее время.
Я надеюсь, что это поможет другим разработчикам бороться с этой проблемой. И, возможно, в будущем Google сможет улучшить компилятор, который делает эту обрезку по умолчанию. Наш файл APK DEX прошел с 8 МБ до 2,9 МБ.
Более новые версии gradle (1.0.0+)
В новых версиях Android-студии (1.0+) обновлен пакет gradle. Были некоторые изменения в том, как работает механизм сборки, поэтому ваш проект gradle теперь может использовать преимущества параметров minifyEnabled и shrinkResources. Текущая версия - 1.1.0.
Сохранение изменений на быстроходной платформе, такой как Android, требует больших усилий, но часто вознаграждается новыми функциями, инструментами и более быстрым временем сборки. Поэтому обновление Android Studio и (тщательное) обновление ваших проектов стоит того времени, когда вы инвестируете.
buildTypes {
debug {
proguardFile 'proguard-project-debug.txt'
minifyEnabled true
shrinkResources true
}
}