Używaj funkcji i interfejsów API w języku Java 8

Wtyczka Androida do obsługi Gradle w wersji 3.0.0 i nowszych obsługuje wszystkie funkcje języka Java 7 oraz podzbiór funkcji języka Java 8, które różnią się w zależności od wersji platformy. Tworząc aplikację za pomocą wtyczki Androida do obsługi Gradle w wersji 4.0.0 lub nowszej, możesz użyć niektórych interfejsów API w języku Java 8 bez wymagania minimalnego poziomu API dla aplikacji.

Na tej stronie opisujemy dostępne w języku Java 8 funkcje języka Java 8, sposoby prawidłowej konfiguracji projektu, aby z nich korzystać, oraz wszystkie znane problemy, które możesz napotkać. Obejrzyj film zawierający omówienie funkcji języka Java 8.

Wtyczka Androida do obsługi Gradle zapewnia wbudowaną obsługę określonych funkcji języka Java 8 i bibliotek innych firm, które z nich korzystają. Domyślny łańcuch narzędzi wdraża nowe funkcje językowe, wykonując transformacje kodu bajtowego (desugar) w ramach kompilacji plików klas D8/R8 w kodzie DEX, jak pokazano na rysunku 1.

Obsługa funkcji języka Java 8 z użyciem transformacji kodu bajtowego „desugar”
Rysunek 1. Obsługa funkcji języka Java 8 z użyciem przekształceń kodu bajtowego desugar.

Obsługa funkcji języka Java 8 (wtyczka do Androida do obsługi Gradle w wersji 3.0.0 lub nowszej)

Aby zacząć korzystać z obsługiwanych funkcji językowych Java 8:

  1. Zaktualizuj wtyczkę Androida do obsługi Gradle do wersji 3.0.0 lub nowszej.
  2. W przypadku każdego modułu, który używa funkcji języka Java 8 (w swoim kodzie źródłowym lub przez zależności), zaktualizuj plik build.gradle lub build.gradle.kts modułu w ten sposób:

Kotlin

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"
    }
}

Odlotowy

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"
    }
}

Gdy tworzysz aplikację za pomocą wtyczki Androida do obsługi Gradle w wersji 3.0.0 lub nowszej, wtyczka nie obsługuje wszystkich funkcji języka Java 8. Poniższe funkcje językowe są dostępne na każdym poziomie interfejsu API:

Funkcja języka Java 8 Uwagi
Wyrażenia lambda Android nie obsługuje serializacji wyrażeń lambda.
Odwołania do metod  
Adnotacje typu Informacje o adnotacji o typie są dostępne tylko w czasie kompilowania, a nie w czasie działania. Platforma obsługuje TYPE w interfejsie API na poziomie 24 i niższym, ale nie obsługuje ElementType.TYPE_USE ani ElementType.TYPE_PARAMETER.
Domyślne i statyczne metody interfejsu  
Powtarzanie adnotacji  

Oprócz tych funkcji językowych Java 8 wtyczka Androida do obsługi Gradle w wersji 3.0.0 i nowszych rozszerza obsługę tagu try-with-resources na wszystkie poziomy interfejsu API Androida.

Desugar nie obsługuje właściwości MethodHandle.invoke ani MethodHandle.invokeExact. Jeśli w Twoim kodzie źródłowym lub jednej z zależności modułów używa się jednej z tych metod, musisz podać właściwość minSdkVersion 26 lub wyższą. W przeciwnym razie pojawi się ten błąd:

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

W niektórych przypadkach moduł może nie korzystać z metod invoke lub invokeExact, nawet jeśli są uwzględnione w zależności biblioteki. Aby nadal używać tej biblioteki z kodem minSdkVersion 25 lub niższym, włącz zmniejszanie kodu i usuń używane metody. Jeśli to nie zadziała, rozważ użycie biblioteki alternatywnej, która nie korzysta z nieobsługiwanych metod.

Odinstalowanie funkcji języka Java w wersji 8 lub nowszej z wtyczki Androida do obsługi Gradle w wersji 3.0.0 lub nowszej i nie powoduje udostępnienia żadnych dodatkowych klas ani interfejsów API (np. java.util.stream.*) w starszych wersjach Androida. Obsługa częściowego odufrowywania interfejsu Java API jest dostępna we wtyczce Androida do obsługi Gradle w wersji 4.0.0 lub nowszej zgodnie z opisem w tej sekcji.

Obsługa odciągania interfejsu API w języku Java 8 lub nowszym (wtyczka Android do obsługi Gradle w wersji 4.0.0 lub nowszej)

Jeśli tworzysz aplikację, korzystając z wtyczki Androida do obsługi Gradle w wersji 4.0.0 lub nowszej, wtyczka rozszerza obsługę wielu interfejsów API w języku Java 8, nie wymagając przy tym minimalnego poziomu API dla aplikacji. W przypadku wtyczki Androida do obsługi Gradle w wersji 7.4.0 lub nowszej kilka interfejsów API w języku Java 11 jest dostępnych również w przypadku wersji 2.0.0 lub nowszej.

Taka dodatkowa obsługa starszych wersji platformy jest możliwa, ponieważ wtyczka 4.0.0 lub nowsza rozszerza mechanizm deugaringu na również interfejsy API języka Java. W aplikacjach obsługujących starsze wersje Androida możesz dodać interfejsy API w standardowych językach, które były dostępne tylko w najnowszych wersjach Androida (np. java.util.streams).

Ten zestaw interfejsów API jest obsługiwany przy tworzeniu aplikacji za pomocą wtyczki Android Gradle w wersji 4.0.0 lub nowszej:

  • Strumienie sekwencyjne (java.util.stream)
  • Podzbiór: java.time
  • java.util.function
  • Ostatnio dodane do: java.util.{Map,Collection,Comparator}
  • Zajęcia opcjonalne (java.util.Optional, java.util.OptionalInt i java.util.OptionalDouble) oraz niektóre nowe zajęcia
  • Poprawki do java.util.concurrent.atomic (nowe metody w usługach AtomicInteger, AtomicLong i AtomicReference)
  • ConcurrentHashMap (z poprawkami błędów w Androidzie 5.0)

Przy wtyczce Androida do obsługi Gradle w wersji 7.4.0 lub nowszej obsługiwane są dodatkowe interfejsy API języka Java 11, takie jak podzbiór pakietu java.nio.file.

Pełną listę obsługiwanych interfejsów API znajdziesz w artykułach na temat interfejsów API Java w wersji 8 lub nowszej dostępnych dzięki odciążaniu oraz interfejsów API Java w wersji 11 i nowszych dostępnych poprzez odinstalowanie.

Aby obsługiwać te interfejsy API języka, wtyczka kompiluje osobny plik DEX, który zawiera implementację brakujących interfejsów API i umieszcza ją w Twojej aplikacji. Proces odpalania przepisuje kod aplikacji tak, aby ta biblioteka była używana w czasie działania.

Aby włączyć obsługę tych języków API na dowolnej wersji platformy Androida:

  1. Zaktualizuj wtyczkę Androida do obsługi Gradle do wersji 4.0.0 (lub nowszej).
  2. W pliku build.gradle lub build.gradle.kts modułu aplikacji umieść:

Kotlin

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")
}

Odlotowy

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'
}

Pamiętaj, że może być też konieczne umieszczenie poprzedniego fragmentu kodu w pliku build.gradle lub build.gradle.kts modułu biblioteki, jeśli:

  • Testy instrumentowane w module biblioteki używają tych językowych interfejsów API (bezpośrednio lub przez moduł biblioteki bądź jego zależności). W ten sposób dostarczysz brakujące interfejsy API do instrumentowanego testowego pakietu APK.

  • Chcesz uruchomić narzędzie Lint w module biblioteki z osobna. Ułatwia to rozpoznawanie prawidłowych zastosowań językowych interfejsów API i unikanie zgłaszania fałszywych ostrzeżeń.

Pamiętaj też, że odpalanie interfejsu API można połączyć z zmniejszaniem, ale tylko przy użyciu kurczaka R8.

Wersje

W tabeli poniżej znajdziesz wersje biblioteki interfejsu API Java 8 lub nowszego oraz minimalną wersję wtyczki Androida do obsługi Gradle, która obsługuje poszczególne wersje:

Wersja Minimalna wersja wtyczki Androida do obsługi Gradle
1.1.9 4.0.0
1.2.3 7.3.0
2.0.3 7.4.0-alfa10

Informacje o wersjach biblioteki interfejsu API Java 8+ znajdziesz w pliku CHANGELOG.md w repozytorium desugar_jdk_libs na GitHubie.