Intereting Posts
Как исправить NPE в ViewRoot # updateBidiOptions? Как использовать один источник библиотеки для нескольких проектов Передача строки в C-код в Android NDK Где хранить конфиденциальную глобальную информацию, такую ​​как ключи API в приложении Android? OnTextChanged vs afterTextChanged в Android – нужны живые примеры Android: Исправлен шрифт ширины в AlertDialog Как лицензировать приложение для Android? Как показать мягкую клавиатуру, когда edittext сфокусирован Электронная почта для редактирования текста Как сделать HorizontalScrollView RIGHT на LEFT Scroll android Почему одна поточная модель используется для обновления пользовательского интерфейса в качестве основного потока? Полная веб-страница и отключенный метадатчик view viewport для всех мобильных браузеров Кнопка Android – Hold для повторения действия Как обрабатывать состояния ошибок с помощью LiveData? Запуск приложения с мгновенным запуском Android-студии очень медленный

Использование Gradle для разделения внешних библиотек в разделенных файлах dex для решения ограничений метода Dalvik 64k для Android

Есть ли proper/easy способ решить ограничение 64k методов с помощью Gradle?

Я имею в виду некоторые пользовательские задачи Gradle для использования предварительно дексированных банок для создания разделенных файлов dex вместо одного classes.dex .

спасибо

Иван

Текущее состояние

В настоящее время я борюсь с GMS: он использует 20 тыс. Методов для использования Google Analytics. Я использую Proguard, чтобы вырезать то, что не нужно, но все же … 72 тыс. Методов и подсчет …

Я могу разделить classes.dex в двух файлах с помощью параметра dx –multi-dex . Я сделал это вручную

 sdk/build-tools/android-4.4W/dx 

И отредактируйте последнюю строку следующим образом:

 exec java $javaOpts -jar "$jarpath" --multi-dex "$@" 

Мой файл APK теперь содержит __classes.dex__ and __classes2.dex__ .

Я пытаюсь динамически загрузить второй файл несколькими способами:

  • Ссылка Dexdex
  • Ссылка Dexter
  • Вторичная ссылка

К сожалению, пока не везет. Я действительно надеюсь, что Google / Facebook / Square гуру может обеспечить правильное решение.

Solutions Collecting From Web of "Использование Gradle для разделения внешних библиотек в разделенных файлах dex для решения ограничений метода Dalvik 64k для Android"

Обновление для Android Gradle plugin 2.2.0: больше невозможно получить доступ к задаче dex , но в обмен additionalParameters входящие в состав dexOptions . Используйте его как

 android { dexOptions { additionalParameters += '--minimal-main-dex' // additionalParameters += '--main-dex-list=$projectDir/<filename>'.toString() // additionalParameters += '--set-max-idx-number=55000' } } 

Обновление для Android Gradle plugin 0.14.0: теперь существует прямая поддержка нескольких multiDexEnabled true через новую директиву multiDexEnabled true (требуется встроенные инструменты 21.1.0, версия 8 репозитория поддержки и Android Studio 0.9).

Оригинальный ответ: с тех пор, как Gradle Android plugin 0.9.0 вы действительно можете передать --multi-dex в dx , добавив это в файл build.gradle вашего приложения:

 afterEvaluate { tasks.matching { it.name.startsWith('dex') }.each { dx -> if (dx.additionalParameters == null) { dx.additionalParameters = ['--multi-dex'] } else { dx.additionalParameters += '--multi-dex' } // Add more additional parameters like this: dx.additionalParameters += '--main-dex-list=class-list.txt' dx.additionalParameters += '--minimal-main-dex' } } 

До сих пор для создания он несколько файлов dex. Чтобы на самом деле использовать несколько файлов dex, посмотрите https://github.com/casidiablo/multidex (который является вилкой будущей библиотеки поддержки MultiDex Google).

В случае, если gms была вашей проблемой, и вы используете gradle

Начиная с версии gms 6.5 вы можете выбрать отдельные библиотеки API

Например, включить только API Карт:

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

И вот полный список:

  com.google.android.gms:play-services-base:6.5.87 com.google.android.gms:play-services-ads:6.5.87 com.google.android.gms:play-services-appindexing:6.5.87 com.google.android.gms:play-services-maps:6.5.87 com.google.android.gms:play-services-location:6.5.87 com.google.android.gms:play-services-fitness:6.5.87 com.google.android.gms:play-services-panorama:6.5.87 com.google.android.gms:play-services-drive:6.5.87 com.google.android.gms:play-services-games:6.5.87 com.google.android.gms:play-services-wallet:6.5.87 com.google.android.gms:play-services-identity:6.5.87 com.google.android.gms:play-services-cast:6.5.87 com.google.android.gms:play-services-plus:6.5.87 com.google.android.gms:play-services-appstate:6.5.87 com.google.android.gms:play-services-wearable:6.5.87 com.google.android.gms:play-services-all-wear:6.5.87 

Пример разбиения на разделы и загрузка различных файлов dex можно найти здесь:

https://code.google.com/p/android-custom-class-loading-sample/

EDIT: для Gradle у вас уже есть ответ

Загрузка пользовательского класса в Dalvik с помощью Gradle (Android New Build System)

Я поддерживаю https://github.com/creativepsyco/secondary-dex-gradle/, и я являюсь градиентом n00b, поэтому я выбрал путь к сценариям BASH, хотя я думаю, что это можно сделать непосредственно в файле сборки. ИЛИ может быть реорганизован для запуска в качестве плагина, я могу сделать это, когда я соглашусь на условия с Gradle. Вот причина моей логики.

Чтобы понять, как разделить DEX, вы должны знать порядок задания системы сборки. Если вы используете gradle, вы должны знать, что в цикле сборки есть серия задач.

Например:

 :sdk:processReleaseJavaRes UP-TO-DATE :sdk:packageReleaseJar :sdk:compileReleaseNdk UP-TO-DATE :sdk:packageReleaseJniLibs UP-TO-DATE :sdk:packageReleaseLocalJar UP-TO-DATE :sdk:packageReleaseRenderscript UP-TO-DATE :sdk:packageReleaseResources UP-TO-DATE :sdk:bundleRelease :app:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE :app:prepareComFacebookAndroidFacebook3141Library 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:compileDebugJava :app:preDexDebug :app:dexDebug :app:processDebugJavaRes UP-TO-DATE :app:validateReleaseConfigSigning :app:packageDebug :app:zipalignDebug :app:assembleDebug 

Чтобы сделать Dexing, вы должны иметь возможность вводить свою настраиваемую задачу между задачами dex * и process *. Если вы можете это сделать, то Multiple DEXing станет проще.

Сценарий Bash здесь по существу делает это, если вы изучите задачу отладки, это будет в основном:

  • Загрузите файл библиотеки Jar в dex, как правило, он специфичен для сборки и существует в папке с exploded-aar для Android-библиотек и запускает на нем инструмент DEX
  • Скопируйте это в папку с ресурсами, которая существует в последней папке libs, которая будет упакована внутри приложения.
  • Все ресурсы библиотеки и т. Д. Уже объединены, а это значит, что необходимо снова распаковать и закрепить файл.

В сценарии построения градиента

  // For Debug simply remove the library from getting dex and create it //----------------------- Extra Debug Step ----------------// def libraryFiles = new ArrayList<?>() def secondaryFile = new ArrayList<?>() variant.dex.libraries.each { File file -> if (!file.absolutePath.contains("lib/unspecified/classes.jar")) { libraryFiles.add(file) } else { secondaryFile.add(file) } } variant.dex.libraries = libraryFiles //----------------------- Extra Debug Step ----------------// packagingTask.dependsOn variant.javaCompile } 

Это вручную удаляет библиотеку из-за того, что ее можно разложить, так что она может быть сгенерирована с помощью сценария bash.

Я думаю, что вы можете разобраться с dexing во время процесса выпуска таким же образом. Другая важная вещь, которую следует отметить, заключается в том, что Proguard Task контролируется плагином android gradle, и вы не можете многое изменить. Проблема с правилами Proguard:

  • Каждый проход proguard отличается, мы не хотим в итоге оказаться в ситуации, когда наши 2 DEXes имеют разные сопоставления proguard
  • Это оставляет нас в ситуации, когда мы не можем програждать наши библиотеки, но это не очень желательно.
  • Должен генерировать файл dex после proguard, чтобы убедиться, что сопоставления совпадают. Gradle не поддерживает объединение активов после Proguard (мы хотим поместить файлы dex в папку с ресурсами)

Другой важный фрагмент кода находится в SecondaryDex.java, который по существу загружает второй файл dex и вводит путь к файлу DEX в путь класса времени выполнения. Вы можете оптимизировать это и просто вводить путь вместо чтения DEX-файла каждый раз, когда приложение возобновляется.

Я сделал дополнительный эксперимент Dex в Google Play Services (который добавляет 20K-методов) и смог разделиться в отдельный файл DEX. Таким образом, мой основной файл dex не затронут раздуванием сервисов Google Play.

Чтобы понять, как работает цикл задач Gradle, вы можете обратиться к источнику BasePlugin.groovy , вы можете видеть, что трудно контролировать некоторые аспекты, пока не будет надлежащего API для доступа к вариантным объектам и задачам сборки.