Если minSdk
вашего приложения равен API 20 или ниже , а само приложение и библиотеки, на которые оно ссылается, превышают 65 536 методов, вы столкнетесь со следующей ошибкой сборки, которая указывает на то, что ваше приложение достигло предела архитектуры сборки Android:
trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.
Более старые версии системы сборки сообщают о другой ошибке, которая указывает на ту же проблему:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
Эти состояния ошибок отображают общее число: 65536. Это число представляет собой общее число ссылок, которые могут быть вызваны кодом в одном файле байт-кода Dalvik Executable (DEX). На этой странице объясняется, как обойти это ограничение, включив конфигурацию приложения, известную как multidex , которая позволяет вашему приложению создавать и читать несколько файлов DEX.
О пределе ссылок 64К
Файлы приложений Android (APK) содержат исполняемые файлы байт-кода в форме файлов Dalvik Executable (DEX) , которые содержат скомпилированный код, используемый для запуска вашего приложения. Спецификация Dalvik Executable ограничивает общее количество методов, на которые можно ссылаться в одном файле DEX, до 65 536, включая методы фреймворка Android, библиотечные методы и методы в вашем собственном коде.
В контексте компьютерной науки термин кило, или K , обозначает 1024 (или 2^10). Поскольку 65 536 равно 64x1024, этот предел называется _пределом ссылки 64K_.Поддержка Multidex до Android 5.0
Версии платформы до Android 5.0 (уровень API 21) используют среду выполнения Dalvik для выполнения кода приложения. По умолчанию Dalvik ограничивает приложения одним файлом байт-кода classes.dex
на APK. Чтобы обойти это ограничение, добавьте библиотеку multidex в файл build.gradle
или build.gradle.kts
на уровне модуля:
Круто
dependencies { def multidex_version = "2.0.1" implementation "androidx.multidex:multidex:$multidex_version" }
Котлин
dependencies { val multidex_version = "2.0.1" implementation("androidx.multidex:multidex:$multidex_version") }
Эта библиотека становится частью основного файла DEX вашего приложения, а затем управляет доступом к дополнительным файлам DEX и коду, который они содержат. Чтобы просмотреть текущие версии этой библиотеки, см. версии multidex .
Более подробную информацию смотрите в разделе о настройке приложения для multidex .Поддержка Multidex для Android 5.0 и выше
Android 5.0 (уровень API 21) и выше использует среду выполнения ART, которая изначально поддерживает загрузку нескольких файлов DEX из файлов APK. ART выполняет предварительную компиляцию во время установки приложения, сканируя файлы classes N .dex
и компилируя их в один файл OAT для выполнения устройством Android. Поэтому, если minSdkVersion
равен 21 или выше, multidex включен по умолчанию, и вам не нужна библиотека multidex.
Дополнительную информацию о среде выполнения Android 5.0 см. в статьях Android Runtime (ART) и Dalvik .
Примечание: При запуске вашего приложения с помощью Android Studio сборка оптимизируется для целевых устройств, на которые вы развертываете. Это включает включение multidex, когда целевые устройства работают под управлением Android 5.0 и выше. Поскольку эта оптимизация применяется только при развертывании вашего приложения с помощью Android Studio, вам все равно может потребоваться настроить сборку выпуска для multidex, чтобы избежать ограничения в 64 КБ.
Избегайте ограничения в 64К
Прежде чем настраивать приложение для использования ссылок на методы размером 64 КБ или более, примите меры по сокращению общего количества ссылок, вызываемых кодом вашего приложения, включая методы, определенные кодом вашего приложения или включенными библиотеками.
Следующие стратегии помогут вам избежать достижения лимита ссылок DEX:
- Проверьте прямые и транзитивные зависимости вашего приложения.
- Подумайте, перевешивает ли ценность любой большой зависимости библиотеки, которую вы включаете в свое приложение, объем кода, добавляемого в приложение. Распространенный, но проблемный шаблон — включать очень большую библиотеку, потому что несколько методов утилиты были полезны. Уменьшение зависимостей кода вашего приложения часто может помочь вам избежать ограничения ссылок DEX.
- Удалить неиспользуемый код с помощью R8
- Включите сжатие кода для запуска R8 для ваших релизных сборок. Включите сжатие, чтобы гарантировать, что вы не отправляете неиспользуемый код с вашими APK. Если сжатие кода настроено правильно, оно также может удалить неиспользуемый код и ресурсы из ваших зависимостей.
Использование этих методов может помочь вам уменьшить общий размер APK и избежать необходимости использования multidex в вашем приложении.
Настройте свое приложение для multidex
Примечание: еслиminSdkVersion
установлен на 21 или выше, multidex включен по умолчанию и вам не нужна библиотека multidex. Если значение minSdkVersion
равно 20 или ниже, то вам необходимо использовать библиотеку multidex и внести следующие изменения в проект вашего приложения:
Измените файл
build.gradle
на уровне модуля, чтобы включить multidex и добавить библиотеку multidex в качестве зависимости, как показано здесь:Круто
android { defaultConfig { ... minSdkVersion 15 targetSdkVersion 33 multiDexEnabled true } ... } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Котлин
android { defaultConfig { ... minSdk = 15 targetSdk = 33 multiDexEnabled = true } ... } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
- В зависимости от того, переопределяете ли вы класс
Application
, выполните одно из следующих действий:Если вы не переопределяете класс
Application
, отредактируйте файл манифеста, чтобы задатьandroid:name
в теге<application>
следующим образом:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application android:name="androidx.multidex.MultiDexApplication" > ... </application> </manifest>
Если вы переопределяете класс
Application
, измените его так, чтобы он расширялMultiDexApplication
, как показано ниже:Котлин
class MyApplication : MultiDexApplication() {...}
Ява
public class MyApplication extends MultiDexApplication { ... }
Если вы переопределяете класс
Application
, но изменить базовый класс невозможно, то вместо этого переопределите методattachBaseContext()
и вызовитеMultiDex.install(this)
, чтобы включить multidex:Котлин
class MyApplication : SomeOtherApplication() { override fun attachBaseContext(base: Context) { super.attachBaseContext(base) MultiDex.install(this) } }
Ява
public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }
Внимание: не выполняйте
MultiDex.install()
или любой другой код через отражение или JNI до завершенияMultiDex.install()
. Трассировка Multidex не будет отслеживать эти вызовы, вызываяClassNotFoundException
или ошибки проверки из-за плохого разделения классов между файлами DEX.
Теперь, когда вы создаете свое приложение, инструменты сборки Android создают основной файл DEX ( classes.dex
) и вспомогательные файлы DEX ( classes2.dex
, classes3.dex
и т. д.) по мере необходимости. Затем система сборки упаковывает все файлы DEX в ваш APK.
Во время выполнения, вместо поиска только в основном файле classes.dex
, API multidex используют специальный загрузчик классов для поиска ваших методов во всех доступных файлах DEX.
Ограничения библиотеки multidex
Библиотека multidex имеет некоторые известные ограничения. При включении библиотеки в конфигурацию сборки приложения учтите следующее:
- Установка файлов DEX во время запуска на раздел данных устройства сложна и может привести к ошибкам Application Not Responding (ANR), если вторичные файлы DEX большие. Чтобы избежать этой проблемы, включите сжатие кода , чтобы минимизировать размер файлов DEX и удалить неиспользуемые части кода.
- При работе на версиях до Android 5.0 (уровень API 21) использование multidex недостаточно для обхода лимита linearalloc ( проблема 37008143 ). Этот лимит был увеличен в Android 4.0 (уровень API 14), но это не решило проблему полностью.
На версиях ниже Android 4.0 вы можете достичь предела linearalloc до достижения предела индекса DEX. Поэтому, если вы ориентируетесь на уровни API ниже 14, тщательно протестируйте эти версии платформы, поскольку у вашего приложения могут возникнуть проблемы при запуске или при загрузке определенных групп классов.
Сокращение кода может уменьшить или даже полностью устранить эти проблемы.
Объявите классы, необходимые в основном файле DEX
При сборке каждого файла DEX для приложения multidex инструменты сборки выполняют сложный процесс принятия решений, чтобы определить, какие классы необходимы в основном файле DEX, чтобы ваше приложение могло успешно запуститься. Если какой-либо класс, требуемый при запуске, не предоставлен в основном файле DEX, то ваше приложение вылетает с ошибкой java.lang.NoClassDefFoundError
.
Инструменты сборки распознают пути кода для кода, доступ к которому осуществляется напрямую из кода вашего приложения. Однако эта проблема может возникнуть, когда пути кода менее заметны, например, когда используемая вами библиотека имеет сложные зависимости. Например, если код использует интроспекцию или вызов методов Java из собственного кода, то эти классы могут не распознаваться как требуемые в первичном файле DEX.
Если вы получаете java.lang.NoClassDefFoundError
, вы должны вручную указать дополнительные классы, требуемые в основном файле DEX, объявив их со свойством multiDexKeepProguard
в вашем типе сборки. Если класс соответствует в файле multiDexKeepProguard
, то этот класс добавляется в основной файл DEX.
свойство multiDexKeepProguard
Файл multiDexKeepProguard
использует тот же формат, что и ProGuard, и поддерживает всю грамматику ProGuard. Для получения дополнительной информации о том, как настроить то, что хранится в вашем приложении, см. раздел Настройте, какой код хранить .
Файл, который вы указываете в multiDexKeepProguard
должен содержать опции -keep
в любом допустимом синтаксисе ProGuard. Например, -keep com.example.MyClass.class
. Вы можете создать файл с именем multidex-config.pro
, который выглядит следующим образом:
-keep class com.example.MyClass -keep class com.example.MyClassToo
Если вы хотите указать все классы в пакете, файл выглядит так:
-keep class com.example.** { *; } // All classes in the com.example package
Затем вы можете объявить этот файл для типа сборки следующим образом:
Круто
android { buildTypes { release { multiDexKeepProguard file('multidex-config.pro') ... } } }
Котлин
android { buildTypes { getByName("release") { multiDexKeepProguard = file("multidex-config.pro") ... } } }
Оптимизация multidex в сборках разработки
Конфигурация multidex требует значительного увеличения времени обработки сборки, поскольку система сборки должна принимать сложные решения о том, какие классы должны быть включены в первичный файл DEX, а какие классы могут быть включены во вторичные файлы DEX. Это означает, что инкрементальные сборки с использованием multidex обычно занимают больше времени и могут потенциально замедлить процесс разработки.
Чтобы сократить более длительное время инкрементальной сборки, используйте pre-dexing для повторного использования вывода multidex между сборками. Pre-dexing опирается на формат ART, доступный только на Android 5.0 (уровень API 21) и выше. Если вы используете Android Studio, IDE автоматически использует pre-dexing при развертывании вашего приложения на устройстве под управлением Android 5.0 (уровень API 21) или выше. Однако, если вы запускаете сборки Gradle из командной строки, вам необходимо установить minSdkVersion
на 21 или выше, чтобы включить pre-dexing.
minSdkVersion
, как показано: Круто
android { defaultConfig { ... multiDexEnabled true // The default minimum API level you want to support. minSdkVersion 15 } productFlavors { // Includes settings you want to keep only while developing your app. dev { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdkVersion 21 } prod { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Котлин
android { defaultConfig { ... multiDexEnabled = true // The default minimum API level you want to support. minSdk = 15 } productFlavors { // Includes settings you want to keep only while developing your app. create("dev") { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdk = 21 } create("prod") { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } } } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
Чтобы узнать больше стратегий, помогающих улучшить скорость сборки из Android Studio или командной строки, прочтите статью Оптимизация скорости сборки . Для получения дополнительной информации об использовании вариантов сборки см. статью Настройка вариантов сборки .
Совет: Если у вас есть разные варианты сборки для разных потребностей multidex, вы можете предоставить разные файлы манифеста для каждого варианта, так что только файл для API уровня 20 и ниже изменяет имя тега <application>
. Вы также можете создать разные подклассы Application
для каждого варианта, так что только подкласс для API уровня 20 и ниже расширяет класс MultiDexApplication
или вызывает MultiDex.install(this)
.
Тестовые мультидексные приложения
При написании тестов инструментирования для приложений multidex дополнительная настройка не требуется, если вы используете MonitoringInstrumentation
или AndroidJUnitRunner
instrumentation. Если вы используете другой Instrumentation
, то вы должны переопределить его метод onCreate()
следующим кодом:
Котлин
fun onCreate(arguments: Bundle) { MultiDex.install(targetContext) super.onCreate(arguments) ... }
Ява
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ... }
Если minSdk
вашего приложения равен API 20 или ниже , а само приложение и библиотеки, на которые оно ссылается, превышают 65 536 методов, вы столкнетесь со следующей ошибкой сборки, которая указывает на то, что ваше приложение достигло предела архитектуры сборки Android:
trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.
Более старые версии системы сборки сообщают о другой ошибке, которая указывает на ту же проблему:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
Эти состояния ошибок отображают общее число: 65536. Это число представляет собой общее число ссылок, которые могут быть вызваны кодом в одном файле байт-кода Dalvik Executable (DEX). На этой странице объясняется, как обойти это ограничение, включив конфигурацию приложения, известную как multidex , которая позволяет вашему приложению создавать и читать несколько файлов DEX.
О пределе ссылок 64К
Файлы приложений Android (APK) содержат исполняемые файлы байт-кода в форме файлов Dalvik Executable (DEX) , которые содержат скомпилированный код, используемый для запуска вашего приложения. Спецификация Dalvik Executable ограничивает общее количество методов, на которые можно ссылаться в одном файле DEX, до 65 536, включая методы фреймворка Android, библиотечные методы и методы в вашем собственном коде.
В контексте компьютерной науки термин кило, или K , обозначает 1024 (или 2^10). Поскольку 65 536 равно 64x1024, этот предел называется _пределом ссылки 64K_.Поддержка Multidex до Android 5.0
Версии платформы до Android 5.0 (уровень API 21) используют среду выполнения Dalvik для выполнения кода приложения. По умолчанию Dalvik ограничивает приложения одним файлом байт-кода classes.dex
на APK. Чтобы обойти это ограничение, добавьте библиотеку multidex в файл build.gradle
или build.gradle.kts
на уровне модуля:
Круто
dependencies { def multidex_version = "2.0.1" implementation "androidx.multidex:multidex:$multidex_version" }
Котлин
dependencies { val multidex_version = "2.0.1" implementation("androidx.multidex:multidex:$multidex_version") }
Эта библиотека становится частью основного файла DEX вашего приложения, а затем управляет доступом к дополнительным файлам DEX и коду, который они содержат. Чтобы просмотреть текущие версии этой библиотеки, см. версии multidex .
Более подробную информацию смотрите в разделе о настройке приложения для multidex .Поддержка Multidex для Android 5.0 и выше
Android 5.0 (уровень API 21) и выше использует среду выполнения ART, которая изначально поддерживает загрузку нескольких файлов DEX из файлов APK. ART выполняет предварительную компиляцию во время установки приложения, сканируя файлы classes N .dex
и компилируя их в один файл OAT для выполнения устройством Android. Поэтому, если minSdkVersion
равен 21 или выше, multidex включен по умолчанию, и вам не нужна библиотека multidex.
Дополнительную информацию о среде выполнения Android 5.0 см. в статьях Android Runtime (ART) и Dalvik .
Примечание: При запуске вашего приложения с помощью Android Studio сборка оптимизируется для целевых устройств, на которые вы развертываете. Это включает включение multidex, когда целевые устройства работают под управлением Android 5.0 и выше. Поскольку эта оптимизация применяется только при развертывании вашего приложения с помощью Android Studio, вам все равно может потребоваться настроить сборку выпуска для multidex, чтобы избежать ограничения в 64 КБ.
Избегайте ограничения в 64К
Прежде чем настраивать приложение для использования ссылок на методы размером 64 КБ или более, примите меры по сокращению общего количества ссылок, вызываемых кодом вашего приложения, включая методы, определенные кодом вашего приложения или включенными библиотеками.
Следующие стратегии помогут вам избежать достижения лимита ссылок DEX:
- Проверьте прямые и транзитивные зависимости вашего приложения.
- Подумайте, перевешивает ли ценность любой большой зависимости библиотеки, которую вы включаете в свое приложение, объем кода, добавляемого в приложение. Распространенный, но проблемный шаблон — включать очень большую библиотеку, потому что несколько методов утилиты были полезны. Уменьшение зависимостей кода вашего приложения часто может помочь вам избежать ограничения ссылок DEX.
- Удалить неиспользуемый код с помощью R8
- Включите сжатие кода для запуска R8 для ваших релизных сборок. Включите сжатие, чтобы гарантировать, что вы не отправляете неиспользуемый код с вашими APK. Если сжатие кода настроено правильно, оно также может удалить неиспользуемый код и ресурсы из ваших зависимостей.
Использование этих методов может помочь вам уменьшить общий размер APK и избежать необходимости использования multidex в вашем приложении.
Настройте свое приложение для multidex
Примечание: еслиminSdkVersion
установлен на 21 или выше, multidex включен по умолчанию и вам не нужна библиотека multidex. Если значение minSdkVersion
равно 20 или ниже, то вам необходимо использовать библиотеку multidex и внести следующие изменения в проект вашего приложения:
Измените файл
build.gradle
на уровне модуля, чтобы включить multidex и добавить библиотеку multidex в качестве зависимости, как показано здесь:Круто
android { defaultConfig { ... minSdkVersion 15 targetSdkVersion 33 multiDexEnabled true } ... } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Котлин
android { defaultConfig { ... minSdk = 15 targetSdk = 33 multiDexEnabled = true } ... } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
- В зависимости от того, переопределяете ли вы класс
Application
, выполните одно из следующих действий:Если вы не переопределяете класс
Application
, отредактируйте файл манифеста, чтобы задатьandroid:name
в теге<application>
следующим образом:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application android:name="androidx.multidex.MultiDexApplication" > ... </application> </manifest>
Если вы переопределяете класс
Application
, измените его так, чтобы он расширялMultiDexApplication
, как показано ниже:Котлин
class MyApplication : MultiDexApplication() {...}
Ява
public class MyApplication extends MultiDexApplication { ... }
Если вы переопределяете класс
Application
, но изменить базовый класс невозможно, то вместо этого переопределите методattachBaseContext()
и вызовитеMultiDex.install(this)
, чтобы включить multidex:Котлин
class MyApplication : SomeOtherApplication() { override fun attachBaseContext(base: Context) { super.attachBaseContext(base) MultiDex.install(this) } }
Ява
public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }
Внимание: не выполняйте
MultiDex.install()
или любой другой код через отражение или JNI до завершенияMultiDex.install()
. Трассировка Multidex не будет отслеживать эти вызовы, вызываяClassNotFoundException
или ошибки проверки из-за плохого разделения классов между файлами DEX.
Теперь, когда вы создаете свое приложение, инструменты сборки Android создают основной файл DEX ( classes.dex
) и вспомогательные файлы DEX ( classes2.dex
, classes3.dex
и т. д.) по мере необходимости. Затем система сборки упаковывает все файлы DEX в ваш APK.
Во время выполнения, вместо поиска только в основном файле classes.dex
, API multidex используют специальный загрузчик классов для поиска ваших методов во всех доступных файлах DEX.
Ограничения библиотеки multidex
Библиотека multidex имеет некоторые известные ограничения. При включении библиотеки в конфигурацию сборки приложения учтите следующее:
- Установка файлов DEX во время запуска на раздел данных устройства сложна и может привести к ошибкам Application Not Responding (ANR), если вторичные файлы DEX большие. Чтобы избежать этой проблемы, включите сжатие кода , чтобы минимизировать размер файлов DEX и удалить неиспользуемые части кода.
- При работе на версиях до Android 5.0 (уровень API 21) использование multidex недостаточно для обхода лимита linearalloc ( проблема 37008143 ). Этот лимит был увеличен в Android 4.0 (уровень API 14), но это не решило проблему полностью.
На версиях ниже Android 4.0 вы можете достичь предела linearalloc до достижения предела индекса DEX. Поэтому, если вы ориентируетесь на уровни API ниже 14, тщательно протестируйте эти версии платформы, поскольку у вашего приложения могут возникнуть проблемы при запуске или при загрузке определенных групп классов.
Сокращение кода может уменьшить или даже полностью устранить эти проблемы.
Объявите классы, необходимые в основном файле DEX
При сборке каждого файла DEX для приложения multidex инструменты сборки выполняют сложный процесс принятия решений, чтобы определить, какие классы необходимы в основном файле DEX, чтобы ваше приложение могло успешно запуститься. Если какой-либо класс, требуемый при запуске, не предоставлен в основном файле DEX, то ваше приложение вылетает с ошибкой java.lang.NoClassDefFoundError
.
Инструменты сборки распознают пути кода для кода, доступ к которому осуществляется напрямую из кода вашего приложения. Однако эта проблема может возникнуть, когда пути кода менее заметны, например, когда используемая вами библиотека имеет сложные зависимости. Например, если код использует интроспекцию или вызов методов Java из собственного кода, то эти классы могут не распознаваться как требуемые в первичном файле DEX.
Если вы получаете java.lang.NoClassDefFoundError
, вы должны вручную указать дополнительные классы, требуемые в основном файле DEX, объявив их со свойством multiDexKeepProguard
в вашем типе сборки. Если класс соответствует в файле multiDexKeepProguard
, то этот класс добавляется в основной файл DEX.
свойство multiDexKeepProguard
Файл multiDexKeepProguard
использует тот же формат, что и ProGuard, и поддерживает всю грамматику ProGuard. Для получения дополнительной информации о том, как настроить то, что хранится в вашем приложении, см. раздел Настройте, какой код хранить .
Файл, который вы указываете в multiDexKeepProguard
должен содержать опции -keep
в любом допустимом синтаксисе ProGuard. Например, -keep com.example.MyClass.class
. Вы можете создать файл с именем multidex-config.pro
, который выглядит следующим образом:
-keep class com.example.MyClass -keep class com.example.MyClassToo
Если вы хотите указать все классы в пакете, файл выглядит так:
-keep class com.example.** { *; } // All classes in the com.example package
Затем вы можете объявить этот файл для типа сборки следующим образом:
Круто
android { buildTypes { release { multiDexKeepProguard file('multidex-config.pro') ... } } }
Котлин
android { buildTypes { getByName("release") { multiDexKeepProguard = file("multidex-config.pro") ... } } }
Оптимизация multidex в сборках разработки
Конфигурация multidex требует значительного увеличения времени обработки сборки, поскольку система сборки должна принимать сложные решения о том, какие классы должны быть включены в первичный файл DEX, а какие классы могут быть включены во вторичные файлы DEX. Это означает, что инкрементальные сборки с использованием multidex обычно занимают больше времени и могут потенциально замедлить процесс разработки.
Чтобы сократить более длительное время инкрементальной сборки, используйте pre-dexing для повторного использования вывода multidex между сборками. Pre-dexing опирается на формат ART, доступный только на Android 5.0 (уровень API 21) и выше. Если вы используете Android Studio, IDE автоматически использует pre-dexing при развертывании вашего приложения на устройстве под управлением Android 5.0 (уровень API 21) или выше. Однако, если вы запускаете сборки Gradle из командной строки, вам необходимо установить minSdkVersion
на 21 или выше, чтобы включить pre-dexing.
minSdkVersion
, как показано: Круто
android { defaultConfig { ... multiDexEnabled true // The default minimum API level you want to support. minSdkVersion 15 } productFlavors { // Includes settings you want to keep only while developing your app. dev { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdkVersion 21 } prod { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation "androidx.multidex:multidex:2.0.1" }
Котлин
android { defaultConfig { ... multiDexEnabled = true // The default minimum API level you want to support. minSdk = 15 } productFlavors { // Includes settings you want to keep only while developing your app. create("dev") { // Enables pre-dexing for command-line builds. When using // Android Studio 2.3 or higher, the IDE enables pre-dexing // when deploying your app to a device running Android 5.0 // (API level 21) or higher, regardless of minSdkVersion. minSdk = 21 } create("prod") { // If you've configured the defaultConfig block for the production version of // your app, you can leave this block empty and Gradle uses configurations in // the defaultConfig block instead. You still need to include this flavor. // Otherwise, all variants use the "dev" flavor configurations. } } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } } } dependencies { implementation("androidx.multidex:multidex:2.0.1") }
Чтобы узнать больше стратегий, помогающих улучшить скорость сборки из Android Studio или командной строки, прочтите статью Оптимизация скорости сборки . Для получения дополнительной информации об использовании вариантов сборки см. статью Настройка вариантов сборки .
Совет: Если у вас есть разные варианты сборки для разных потребностей multidex, вы можете предоставить разные файлы манифеста для каждого варианта, так что только файл для API уровня 20 и ниже изменяет имя тега <application>
. Вы также можете создать разные подклассы Application
для каждого варианта, так что только подкласс для API уровня 20 и ниже расширяет класс MultiDexApplication
или вызывает MultiDex.install(this)
.
Тестовые мультидексные приложения
При написании тестов инструментирования для приложений multidex дополнительная настройка не требуется, если вы используете MonitoringInstrumentation
или AndroidJUnitRunner
instrumentation. Если вы используете другой Instrumentation
, то вы должны переопределить его метод onCreate()
следующим кодом:
Котлин
fun onCreate(arguments: Bundle) { MultiDex.install(targetContext) super.onCreate(arguments) ... }
Ява
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ... }