Используйте функции и API языка Java 8.

Плагин Android Gradle 3.0.0 и более поздних версий поддерживает все функции языка Java 7 и подмножество функций языка Java 8, которые зависят от версии платформы. При создании приложения с использованием плагина Android Gradle 4.0.0 и выше вы можете использовать некоторые API языка Java 8, не требуя минимального уровня API для вашего приложения.

На этой странице описаны функции языка Java 8, которые вы можете использовать, как правильно настроить проект для их использования, а также любые известные проблемы, с которыми вы можете столкнуться. В следующем видео представлен обзор возможностей языка Java 8.

Плагин Android Gradle обеспечивает встроенную поддержку использования определенных функций языка Java 8 и сторонних библиотек, которые их используют. Инструментальная цепочка по умолчанию реализует новые возможности языка, выполняя преобразования байт-кода, называемые desugar , как часть компиляции файлов классов D8/R8 в код DEX, как показано на рисунке 1.

Поддержка функций языка Java 8 с использованием преобразований байт-кода desugar.
Рисунок 1. Поддержка функций языка Java 8 с использованием преобразований байт-кода desugar .

Поддержка функций языка Java 8 (плагин Android Gradle 3.0.0+)

Чтобы начать использовать поддерживаемые функции языка Java 8:

  1. Обновите плагин Android Gradle до версии 3.0.0 или выше.
  2. Для каждого модуля, использующего функции языка Java 8 (в исходном коде или через зависимости), обновите файл build.gradle или build.gradle.kts модуля, как показано ниже:

Котлин

android {
    ...
    // Configure only for each module that uses Java 8
    // language features (either in its source code or
    // through dependencies).
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

классный

android {
    ...
    // Configure only for each module that uses Java 8
    // language features (either in its source code or
    // through dependencies).
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

При создании приложения с использованием подключаемого модуля Android Gradle 3.0.0 и более поздних версий он не поддерживает все функции языка Java 8. Следующие функции языка доступны на любом уровне API:

Функция языка Java 8 Примечания
Лямбда-выражения Android не поддерживает сериализацию лямбда-выражений.
Ссылки на методы
Введите аннотации Информация о аннотации типа доступна только во время компиляции, а не во время выполнения. Платформа поддерживает TYPE на уровне API 24 и ниже, но не ElementType.TYPE_USE или ElementType.TYPE_PARAMETER .
Методы интерфейса по умолчанию и статические.
Повторяющиеся аннотации

В дополнение к этим функциям языка Java 8 плагин Android Gradle версии 3.0.0 и выше расширяет поддержку try -with-resources на все уровни Android API.

Desugar не поддерживает MethodHandle.invoke или MethodHandle.invokeExact . Если ваш исходный код или одна из зависимостей вашего модуля использует один из этих методов, вам необходимо указать minSdkVersion 26 или выше. В противном случае вы получите следующую ошибку:

Dex: Error converting bytecode to dex:
Cause: signature-polymorphic method called without --min-sdk-version >= 26

В некоторых случаях ваш модуль может не использовать методы invoke или invokeExact , даже если они включены в зависимость библиотеки. Чтобы продолжать использовать эту библиотеку с minSdkVersion 25 или ниже, включите сжатие кода для удаления неиспользуемых методов. Если это не сработает, рассмотрите возможность использования альтернативной библиотеки, не использующей неподдерживаемые методы.

Язык Java 8+ поддерживает удаление сахара в подключаемом модуле Android Gradle 3.0.0 и выше и не делает никаких дополнительных классов и API (таких как java.util.stream.* ) доступными для использования в старых версиях Android. Поддержка частичной очистки Java API доступна в плагине Android Gradle 4.0.0 или более поздней версии, как описано в следующем разделе.

Поддержка очистки API Java 8+ (плагин Android Gradle 4.0.0+)

Если вы создаете свое приложение с использованием подключаемого модуля Android Gradle 4.0.0 или более поздней версии, этот подключаемый модуль расширяет поддержку использования ряда API-интерфейсов языка Java 8, не требуя минимального уровня API для вашего приложения. С плагином Android Gradle 7.4.0 или более поздней версии ряд API-интерфейсов языка Java 11 также доступен с очищенной библиотекой 2.0.0 или более поздней версии.

Эта дополнительная поддержка для более старых версий платформы возможна, поскольку плагин 4.0.0 и выше расширяет механизм обессеривания, позволяя также очищать API языка Java. Вы можете включить стандартные языковые API, которые были доступны только в последних выпусках Android (например, java.util.streams ), в приложения, поддерживающие более старые версии Android.

При создании приложения с использованием плагина Android Gradle 4.0.0 или более поздней версии поддерживается следующий набор API:

  • Последовательные потоки ( java.util.stream )
  • Подмножество java.time
  • java.util.function
  • Недавние дополнения к java.util.{Map,Collection,Comparator}
  • Опциональные возможности ( java.util.Optional , java.util.OptionalInt и java.util.OptionalDouble ) и некоторые новые классы.
  • Некоторые дополнения к java.util.concurrent.atomic (новые методы AtomicInteger , AtomicLong и AtomicReference )
  • ConcurrentHashMap (с исправлениями ошибок для Android 5.0)

С плагином Android Gradle 7.4.0 или выше поддерживаются дополнительные API Java 11, такие как подмножество пакета java.nio.file .

Полный список поддерживаемых API см. на странице API-интерфейсы Java 8+, доступные посредством обессеривания, и API-интерфейсы Java 11+, доступные посредством обессеривания .

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

Чтобы включить поддержку этих языковых API в любой версии платформы Android:

  1. Обновите плагин Android Gradle до версии 4.0.0 (или выше).
  2. Включите следующее в файл build.gradle или build.gradle.kts вашего модуля приложения :

Котлин

android {
    defaultConfig {
        // Required when setting minSdkVersion to 20 or lower
        multiDexEnabled = true
    }

    compileOptions {
        // Flag to enable support for the new language APIs

        // For AGP 4.1+
        isCoreLibraryDesugaringEnabled = true
        // For AGP 4.0
        // coreLibraryDesugaringEnabled = true

        // Sets Java compatibility to Java 8
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

dependencies {
    // For AGP 7.4+
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
    // For AGP 7.3
    // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.3")
    // For AGP 4.0 to 7.2
    // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.9")
}

классный

android {
    defaultConfig {
        // Required when setting minSdkVersion to 20 or lower
        multiDexEnabled true
    }

    compileOptions {
        // Flag to enable support for the new language APIs
        coreLibraryDesugaringEnabled true
        // Sets Java compatibility to Java 8
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // For AGP 7.4+
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
    // For AGP 7.3
    // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.3'
    // For AGP 4.0 to 7.2
    // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.9'
}

Обратите внимание, что вам также может потребоваться включить предыдущий фрагмент кода в файл build.gradle или build.gradle.kts библиотечного модуля, если:

  • Инструментированные тесты библиотечного модуля используют эти языковые API (либо напрямую, либо через библиотечный модуль или его зависимости). Это сделано для того, чтобы в вашем инструментированном тестовом APK были предоставлены недостающие API.

  • Вы хотите запустить lint на библиотечном модуле изолированно. Это поможет lint распознать допустимое использование языковых API и избежать ложных предупреждений.

Также обратите внимание, что обессахаривание API можно сочетать с сжатием, но только при использовании устройства сжатия R8.

Версии

В следующей таблице показаны версии библиотеки API Java 8+ и минимальная версия плагина Android Gradle, поддерживающая каждую версию:

Версия Минимальная версия плагина Android Gradle
1.1.9 4.0.0
1.2.3 7.3.0
2.0.3 7.4.0-альфа10

Подробную информацию о версиях библиотеки API Java 8+ см. в файле CHANGELOG.md в репозитории desugar_jdk_libs GitHub.