d8
— это инструмент командной строки, который Android Studio и плагин Android Gradle используют для компиляции байт-кода Java вашего проекта в байт-код DEX, который работает на устройствах Android. d8
позволяет использовать функции языка Java 8 в коде вашего приложения.
d8
также включен как отдельный инструмент в Android Build Tools 28.0.1 и более поздних версий: android_sdk /build-tools/ version /
.
Общее использование
d8
требует только путь к скомпилированному байт-коду Java, который вы хотите преобразовать в байт-код DEX. Например:
d8 MyProject/app/build/intermediates/classes/debug/*/*.class
Входной байт-код может представлять собой любую комбинацию файлов или контейнеров *.class
, например файлов JAR, APK или ZIP. Вы также можете включить файлы DEX для d8
для объединения с выходными данными DEX, что полезно при включении выходных данных инкрементной сборки.
По умолчанию d8
компилирует байт-код Java в оптимизированные файлы DEX и включает отладочную информацию, которую вы можете использовать для отладки кода во время выполнения. Однако вы можете включить дополнительные флаги для выполнения инкрементной сборки, указать классы, которые должны быть скомпилированы в основной файл DEX, и указать пути к дополнительным ресурсам, необходимым для использования функций языка Java 8.
d8 path-to-input-files [options]
В следующей таблице описаны дополнительные флаги, которые вы можете использовать с d8
:
Вариант | Описание |
---|---|
--debug | Скомпилируйте байт-код DEX, чтобы включить отладочную информацию, например таблицы символов отладки. Эта опция включена по умолчанию. Чтобы включить отладочную информацию в байт-код DEX, При компиляции файлов DEX для релизной версии вашего приложения или библиотеки вместо этого используйте флаг |
--release | Скомпилируйте байт-код DEX без отладочной информации. Однако Передайте этот флаг при компиляции байт-кода для публичного выпуска. |
--output path | Укажите желаемый путь для вывода DEX. По умолчанию Если вы укажете путь и имя файла ZIP или JAR, |
--lib android_sdk /platforms/ api-level /android.jar | Укажите путь к android.jar вашего Android SDK. Этот флаг необходим при компиляции байт-кода, использующего возможности языка Java 8 . |
--classpath path | Укажите ресурсы пути к классам, которые могут потребоваться d8 для компиляции файлов DEX вашего проекта. В частности, d8 требует, чтобы вы указали определенные ресурсы при компиляции байт-кода, использующего возможности языка Java 8 . |
--min-api number | Укажите минимальный уровень API, который должны поддерживать выходные файлы DEX. |
--intermediate | Передайте этот флаг, чтобы сообщить d8 , что вы не компилируете полный набор байт-кода Java вашего проекта. Этот флаг полезен при выполнении инкрементных сборок. Вместо компиляции оптимизированных файлов DEX, которые вы ожидаете запустить на устройстве, d8 создает промежуточные файлы DEX и сохраняет их в указанном выходном или пути по умолчанию.Если вы хотите скомпилировать файлы DEX, которые собираетесь запускать на устройстве, исключите этот флаг и укажите путь к промежуточным классам DEX в качестве входных данных. |
--file-per-class | Скомпилируйте каждый класс в отдельные файлы DEX. Включение этого флага позволяет выполнять дополнительные инкрементные сборки, перекомпилируя только те классы, которые изменились. При выполнении инкрементных сборок с использованием плагина Android Gradle эта оптимизация включена по умолчанию. Вы не можете использовать этот флаг, одновременно указав |
--no-desugaring | Отключите функции языка Java 8. Используйте этот флаг только в том случае, если вы не собираетесь компилировать байт-код Java, использующий функции языка Java 8. |
--main-dex-list path | Укажите текстовый файл, в котором перечислены классы Поскольку система Android при запуске приложения сначала загружает основной файл DEX, вы можете использовать этот флаг для определения приоритета определенных классов при запуске, компилируя их в основной файл DEX. Это особенно полезно при поддержке устаревшей мультидексной библиотеки, поскольку во время выполнения доступны только классы в основном файле DEX, пока не будет загружена устаревшая мультидексная библиотека. Имейте в виду, что каждый файл DEX по-прежнему должен соответствовать эталонному пределу в 64 КБ . Поэтому не указывайте слишком много классов для основного файла DEX, иначе вы получите ошибку компиляции. По умолчанию при указании классов с помощью Вы не можете использовать этот флаг, одновременно указав |
--pg-map file | Используйте file в качестве файла сопоставления для распространения. |
--file-per-class-file | Создайте отдельный файл DEX для каждого входного файла .class. Сохраняйте синтетические классы вместе с исходным классом. |
--desugared-lib file | Укажите конфигурацию библиотеки без сахара. file представляет собой очищенный файл конфигурации библиотеки в формате JSON. |
--main-dex-rules file | Proguard сохраняет правила размещения классов в основном файле DEX. |
--main-dex-list-output file | Выведите результирующий основной список DEX в |
| Принудительно включить код утверждения, сгенерированный javac . |
| Принудительно отключить код утверждения, сгенерированный javac . Это обработка кода утверждения javac по умолчанию при создании файлов DEX. |
| Не изменяйте код утверждения, сгенерированный javac . Это обработка кода утверждения javac по умолчанию при создании файлов class . |
| Измените код утверждения, сгенерированный javac и kotlinc , чтобы вызывать handler method метода при каждой ошибке утверждения, а не выдавать его. handler method указывается как имя класса, за которым следует точка и имя метода. Метод-обработчик должен принимать один аргумент типа java.lang.Throwable и возвращать тип void . |
--thread-count number of threads | Укажите количество потоков, которые будут использоваться для компиляции. Если не указано, число основано на эвристике с учетом количества ядер. |
--map-diagnostics[ : type ] from-level to-level | Диагностика карты type (по умолчанию любой), сообщаемая как from-level to to-level , где from-level и to-level — это «информация», «предупреждение» или «ошибка», а необязательный type — простой или полное имя типа Java диагностики. Если type не указан, сопоставляются все диагностики на from-level . Обратите внимание, что фатальные ошибки компилятора не могут быть отображены. |
--version | Распечатайте версию d8 , которую вы сейчас используете. |
--help | Распечатать текст справки по использованию d8 . |
Выполнение дополнительных сборок
Чтобы повысить скорость сборки во время разработки, например, для сборок непрерывной интеграции, попросите d8
скомпилировать только подмножество байт-кода Java вашего проекта. Например, если вы включите индексирование для каждого класса, вы сможете перекомпилировать только те классы, которые вы изменили с момента предыдущей сборки.
Следующая команда выполняет инкрементную сборку нескольких классов и включает индексацию для каждого класса. Команда также указывает выходной каталог для инкрементной сборки.
d8 MainActivity.class R.class --intermediate --file-per-class --output ~/build/intermediate/dex
Когда d8
выполняет инкрементную сборку, он сохраняет дополнительную информацию в выходных данных DEX. Позже d8
использует эту информацию для правильной обработки параметра --main-dex-list
и объединения файлов DEX во время полной сборки вашего приложения.
Например, при обработке лямбда-классов Java 8 d8
отслеживает, какие лямбда-классы созданы для каждого входного класса. Во время полной сборки, когда d8
включает класс в основной файл DEX, он проверяет метаданные, чтобы убедиться, что все лямбда-классы, созданные для этого класса, также включены в основной файл DEX.
Если вы уже скомпилировали весь байт-код вашего проекта в файлы DEX в нескольких инкрементных сборках, выполните полную сборку, передав каталог промежуточных файлов DEX в d8
, как показано в следующей команде. Кроме того, вы можете указать классы, которые d8
должен скомпилировать в основной файл DEX, используя --main-dex-list
. Поскольку входные данные представляют собой набор файлов, которые уже скомпилированы в байт-код DEX, эта сборка должна завершиться быстрее, чем чистая сборка.
d8 ~/build/intermediate/dex --release --main-dex-list ~/build/classes.txt --output ~/build/release/dex
Скомпилируйте байт-код, использующий функции языка Java 8.
d8
позволяет вам использовать функции языка Java 8 в вашем коде посредством процесса компиляции, называемого desugaring . Desugaring преобразует эти полезные функции языка в байт-код, который может работать на платформе Android.
Android Studio и плагин Android Gradle включают ресурсы пути к классам, которые необходимы d8
для включения удаления сахара. Однако при использовании d8
из командной строки вам необходимо включить их самостоятельно.
Одним из таких ресурсов является android.jar
из целевого Android SDK. Этот ресурс включает набор API-интерфейсов платформы Android. Укажите его путь, используя флаг --lib
.
Другим ресурсом является набор байт-кода Java, скомпилированный в ваш проект, который вы в настоящее время не компилируете в байт-код DEX, но который требуется для компиляции других классов в байт-код DEX.
Например, если ваш код использует методы интерфейса по умолчанию и статические методы интерфейса , которые являются особенностью языка Java 8, вам необходимо использовать этот флаг, чтобы указать путь ко всему байт-коду Java вашего проекта, даже если вы не собираетесь компилировать все байт-код в байт-код DEX. Это потому, что d8
требует этой информации для понимания кода вашего проекта и разрешения вызовов методов интерфейса.
В следующем примере кода выполняется инкрементальная сборка класса, который обращается к методу интерфейса по умолчанию:
d8 MainActivity.class --intermediate --file-per-class --output ~/build/intermediate/dex --lib android_sdk/platforms/api-level/android.jar --classpath ~/build/javac/debug