Версии Java в сборках Android

Независимо от того, написан ли ваш исходный код на Java, Kotlin или на обоих языках, в нескольких местах вам придется выбрать версию языка JDK или Java для вашей сборки.

Обзор взаимосвязей JDK в сборке Gradle
Рисунок 1. Взаимосвязи JDK в сборке

Глоссарий

Комплект разработчика Java (JDK)
Комплект разработчика Java (JDK) содержит:
  • Инструменты, такие как компилятор, профилировщик и создатель архивов. Они используются за кулисами во время сборки для создания вашего приложения.
  • Библиотеки, содержащие API, которые можно вызывать из исходного кода Kotlin или Java. Обратите внимание, что не все функции доступны на Android.
  • Виртуальная машина Java (JVM) — интерпретатор, который выполняет приложения Java. JVM используется для запуска Android Studio IDE и инструмента сборки Gradle. JVM не используется на устройствах Android или эмуляторах.
Среда выполнения JetBrains (JBR)
JetBrains Runtime (JBR) — это улучшенный JDK, распространяемый вместе с Android Studio. Он включает несколько оптимизаций для использования в Studio и связанных продуктах JetBrains, но также может использоваться для запуска других приложений Java.

Как выбрать JDK для запуска Android Studio?

Мы рекомендуем использовать JBR для запуска Android Studio. Он развертывается и используется для тестирования Android Studio и включает улучшения для оптимального использования Android Studio. Чтобы обеспечить это, не устанавливайте переменную среды STUDIO_JDK .

Скрипты запуска для Android Studio ищут JVM в следующем порядке:

  1. Переменная среды STUDIO_JDK
  2. Каталог studio.jdk (в дистрибутиве Android Studio)
  3. Каталог jbr (JetBrains Runtime), в дистрибутиве Android Studio. Рекомендуется.
  4. Переменная среды JDK_HOME
  5. Переменная среды JAVA_HOME
  6. исполняемый файл java в переменной среды PATH

Как выбрать, какой JDK будет запускать мои сборки Gradle?

Если вы запускаете Gradle с помощью кнопок в Android Studio, то для запуска Gradle используется JDK, установленный в настройках Android Studio. Если вы запускаете Gradle в терминале, внутри или вне Android Studio, переменная среды JAVA_HOME (если она установлена) определяет, какой JDK запускает скрипты Gradle. Если JAVA_HOME не установлена, то используется команда java в переменной среды PATH .

Для получения наиболее согласованных результатов убедитесь, что вы установили переменную среды JAVA_HOME и конфигурацию Gradle JDK в Android Studio на тот же JDK.

При запуске сборки Gradle создает процесс, называемый демоном , для выполнения самой сборки. Этот процесс можно использовать повторно, если сборки используют ту же версию JDK и Gradle. Повторное использование демона сокращает время запуска новой JVM и инициализации системы сборки.

Если вы запускаете сборки с разными версиями JDK или Gradle, создаются дополнительные демоны, потребляющие больше ресурсов ЦП и памяти.

Конфигурация Gradle JDK в Android Studio

Чтобы изменить конфигурацию Gradle JDK существующего проекта, откройте настройки Gradle из Файл (или Android Studio на macOS) > Настройки > Сборка, выполнение, развертывание > Инструменты сборки > Gradle . Раскрывающийся список Gradle JDK содержит следующие параметры для выбора:

  • Макросы, такие как JAVA_HOME и GRADLE_LOCAL_JAVA_HOME
  • Записи таблицы JDK в формате vendor-version , например jbr-17 которые хранятся в файлах конфигурации Android.
  • Загрузка JDK
  • Добавление определенного JDK
  • Локально обнаруженные JDK из установочного каталога JDK операционной системы по умолчанию

Выбранный параметр сохраняется в параметре gradleJvm в файле .idea/gradle.xml проекта, а его разрешение пути JDK используется для запуска Gradle при запуске через Android Studio.

Рисунок 2. Настройки Gradle JDK в Android Studio.

Макросы позволяют динамически выбирать путь JDK проекта:

  • JAVA_HOME : использует переменную окружения с тем же именем
  • GRADLE_LOCAL_JAVA_HOME : использует свойство java.home в файле .gradle/config.properties которое по умолчанию соответствует среде выполнения JetBrains.

Выбранный JDK используется для запуска сборки Gradle и разрешения ссылок JDK API при редактировании скриптов сборки и исходного кода. Обратите внимание, что указанный compileSdk еще больше ограничит, какие символы Java будут доступны при редактировании и сборке исходного кода.

Обязательно выберите версию JDK, которая выше или равна версиям JDK, используемым плагинами, которые вы используете в своей сборке Gradle. Чтобы определить минимальную требуемую версию JDK для Android Gradle Plugin (AGP), см. таблицу совместимости в примечаниях к выпуску .

Например, для Android Gradle Plugin версии 8.x требуется JDK 17. Если вы попытаетесь запустить сборку Gradle, которая использует его с более ранней версией JDK, вы получите сообщение следующего вида:

An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
      Your current JDK is located in /usr/local/buildtools/java/jdk
      You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.

Какие API Java я могу использовать в исходном коде Java или Kotlin?

Приложение Android может использовать некоторые API, определенные в JDK, но не все. Android SDK определяет реализации многих функций библиотеки Java как часть своих доступных API. Свойство compileSdk указывает, какую версию Android SDK использовать при компиляции исходного кода Kotlin или Java.

Котлин

android {
    ...
    compileSdk = 33
}

Круто

android {
    ...
    compileSdk 33
}

Каждая версия Android поддерживает определенную версию JDK и подмножество доступных API Java. Если вы используете API Java, доступный в compileSdk , который недоступен в указанном minSdk , вы можете использовать API в более ранней версии Android с помощью процесса, известного как desugaring . См. API Java 11+, доступные через desugaring для поддерживаемых API.

Используйте эту таблицу, чтобы определить, какая версия Java поддерживается каждым API Android, а также где найти подробную информацию о доступных API Java.

андроид Ява Поддерживаемые API и языковые функции
14 (API 34) 17 Основные библиотеки
13 (API 33) 11 Основные библиотеки
12 (API 32) 11 Java-API
11 и ниже Версии Android

Какой JDK компилирует мой исходный код Java?

Java toolchain JDK содержит компилятор Java, используемый для компиляции любого исходного кода Java. Этот JDK также запускает javadoc и unit-тесты во время сборки.

По умолчанию набор инструментов соответствует JDK, используемому для запуска Gradle. Если вы используете значение по умолчанию и запускаете сборку на разных машинах (например, на локальной машине и на отдельном сервере Continuous Integration), результаты сборки могут отличаться, если используются разные версии JDK.

Чтобы создать более согласованную сборку, вы можете явно указать версию Java toolchain. Указав это:

  • Находит совместимый JDK в системе, где выполняется сборка.
    • Если совместимого JDK не существует (и определен инструментарий разрешения цепочки), загружает его.
  • Предоставляет API-интерфейсы Java для вызовов из исходного кода.
  • Компилирует исходный код Java, используя его версию на языке Java.
  • Предоставляет значения по умолчанию для sourceCompatibility и targetCompatibility .

Мы рекомендуем вам всегда указывать набор инструментов Java и либо убедиться, что указанный JDK установлен, либо добавить в свою сборку решатель набора инструментов .

Вы можете указать набор инструментов, независимо от того, написан ли ваш исходный код на Java, Kotlin или на обоих языках. Укажите набор инструментов на верхнем уровне файла build.gradle(.kts) вашего модуля.

Укажите версию набора инструментов Java следующим образом:

Котлин

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

Круто

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

Это работает, если вашим источником является Kotlin, Java или их смесь.

Версия JDK набора инструментов может быть такой же, как и JDK, используемый для запуска Gradle, но имейте в виду, что они служат разным целям.

Какие исходные функции языка Java я могу использовать в своем исходном коде Java?

Свойство sourceCompatibility определяет, какие возможности языка Java доступны во время компиляции исходного кода Java. Оно не влияет на исходный код Kotlin.

Укажите sourceCompatibility в файле build.gradle(.kts) вашего модуля следующим образом:

Котлин

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

Круто

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

Если не указано, это свойство по умолчанию соответствует версии Java toolchain . Если вы не используете Java toolchain, то по умолчанию используется версия, выбранная плагином Android Gradle (например, Java 8 или выше).

Какие двоичные функции Java можно использовать при компиляции исходного кода Kotlin или Java?

Свойства targetCompatibility и jvmTarget определяют версию формата класса Java, используемую при генерации байт-кода для скомпилированного исходного кода Java и Kotlin соответственно.

Некоторые функции Kotlin существовали до того, как были добавлены эквивалентные функции Java. Ранним компиляторам Kotlin приходилось создавать собственный способ представления этих функций Kotlin. Некоторые из этих функций были позже добавлены в Java. С более поздними уровнями jvmTarget компилятор Kotlin мог напрямую использовать функцию Java, что могло привести к повышению производительности.

Различные версии Android поддерживают различные версии Java. Вы можете воспользоваться дополнительными функциями Java, увеличив targetCompatibility и jvmTarget , но это может заставить вас также увеличить минимальную версию Android SDK , чтобы обеспечить доступность функции.

Обратите внимание, что targetCompatibility должно быть больше или равно sourceCompatibility . На практике sourceCompatibility , targetCompatibility и jvmTarget должны, как правило, использовать одно и то же значение. Вы можете задать их следующим образом:

Котлин

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

Круто

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget '17'
    }
}

Если не указано, эти свойства по умолчанию соответствуют версии Java toolchain . Если вы не используете Java toolchain, то значения по умолчанию могут отличаться и вызывать проблемы при сборке. Поэтому мы рекомендуем вам всегда явно указывать эти значения или использовать Java toolchain .