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

Wtyczka Androida do obsługi Gradle w wersji 3.0.0 lub nowszej obsługuje wszystkie funkcje języka Java 7 i podzbiór funkcji języka Java 8, które różnią się w zależności od wersji platformy. Jeśli tworzysz aplikację za pomocą wtyczki Androida do obsługi Gradle w wersji 4.0.0 lub nowszej, możesz używać niektórych interfejsów API języka Java 8 bez konieczności określania minimalnego poziomu interfejsu API dla aplikacji.

Na tej stronie opisujemy funkcje języka Java 8, których możesz używać, sposób prawidłowego skonfigurowania projektu, aby z nich korzystać, oraz znane problemy, które możesz napotkać. Obejrzyj ten film, aby zapoznać się z funkcjami języka Java 8.

Wtyczka Androida do obsługi Gradle zapewnia wbudowaną obsługę niektórych funkcji języka Java 8 i bibliotek innych firm, które z nich korzystają. Domyślny łańcuch narzędzi implementuje nowe funkcje języka, wykonując przekształcenia kodu bajtowego, zwane desugar, w ramach kompilacji D8/R8 plików klas na kod DEX, jak pokazano na rysunku 1.

Obsługa funkcji języka Java 8 za pomocą przekształceń kodu bajtowego `desugar`
Rysunek 1. Obsługa funkcji języka Java 8 za pomocą przekształceń kodu bajtowego desugar.

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

Aby zacząć korzystać z obsługiwanych funkcji języka 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 korzysta z funkcji języka Java 8 (w kodzie źródłowym lub przez zależności), zaktualizuj plik build.gradle lub build.gradle.kts modułu w sposób pokazany poniżej:

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

Dynamiczny

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

Jeśli kompilujesz 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. Na każdym poziomie interfejsu API dostępne są te funkcje językowe:

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 adnotacjach typu są dostępne tylko w czasie kompilowania, a nie w czasie działania. Platforma obsługuje TYPE na poziomie interfejsu API 24 i niższym, ale nie ElementType.TYPE_USE ani ElementType.TYPE_PARAMETER.
Domyślne i statyczne metody interfejsu  
Powtarzające się adnotacje  

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

Desugar nie obsługuje MethodHandle.invoke ani MethodHandle.invokeExact. Jeśli Twój kod źródłowy lub jedna z zależności modułu używa jednej z tych metod, musisz określić minSdkVersion 26 lub wyższą wersję. 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 używać metod invoke ani invokeExact, nawet jeśli są one uwzględnione w zależności biblioteki. Aby nadal używać tej biblioteki w wersji minSdkVersion 25 lub niższej, włącz zmniejszanie kodu, aby usunąć nieużywane metody. Jeśli to nie pomoże, rozważ użycie innej biblioteki, która nie korzysta z nieobsługiwanych metod.

Funkcje języka Java 8+ odlukrzają się we wtyczce Android Gradle w wersji 3.0.0 lub nowszej i nie udostępniają żadnych dodatkowych klas ani interfejsów API (takich jak java.util.stream.*) do użycia w starszych wersjach Androida. Obsługa częściowego odlukrzania interfejsu Java API jest dostępna od wtyczki Androida do obsługi Gradle w wersji 4.0.0, jak opisano w następnej sekcji.

Obsługa odlukrzania interfejsu API Java 8+ (wtyczka Androida do obsługi Gradle w wersji 4.0.0 lub nowszej)

Jeśli tworzysz aplikację za pomocą wtyczki Androida do obsługi Gradle w wersji 4.0.0 lub nowszej, wtyczka rozszerza obsługę wielu interfejsów API języka Java 8 bez konieczności określania minimalnego poziomu interfejsu API dla aplikacji. W przypadku wtyczki Androida do obsługi Gradle w wersji 7.4.0 lub nowszej wiele interfejsów API języka Java 11 jest też dostępnych z odcukrzoną biblioteką w wersji 2.0.0 lub nowszej.

Ta dodatkowa obsługa starszych wersji platformy jest możliwa, ponieważ wtyczka w wersji 4.0.0 lub nowszej rozszerza mechanizm odlukrzania, aby odlukrzać również interfejsy API języka Java. W aplikacjach obsługujących starsze wersje Androida możesz uwzględniać standardowe interfejsy API języka, które były dostępne tylko w ostatnich wersjach Androida (takich jak java.util.streams).

Jeśli tworzysz aplikację za pomocą wtyczki Androida do obsługi Gradle w wersji 4.0.0 lub nowszej, obsługiwane są te interfejsy API:

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

Wtyczka Androida do obsługi Gradle w wersji 7.4.0 lub nowszej obsługuje dodatkowe interfejsy API Javy 11, takie jak podzbiór pakietu java.nio.file.

Pełną listę obsługiwanych interfejsów API znajdziesz w artykułach Interfejsy API Javy 8+ dostępne dzięki odlukrzaniu i Interfejsy API Javy 11+ dostępne dzięki odlukrzaniu.

Aby obsługiwać te interfejsy API języka, wtyczka kompiluje oddzielny plik DEX, który zawiera implementację brakujących interfejsów API, i dołącza go do aplikacji. Proces odlukrzania przepisuje kod aplikacji, aby w czasie działania używała tej biblioteki. Kod źródłowy skompilowany do osobnego pliku DEX jest dostępny w repozytorium desugar_jdk_libs na GitHubie.

Aby włączyć obsługę tych interfejsów API języka w dowolnej wersji platformy Android:

  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ść te informacje:

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

Dynamiczny

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ć konieczne dołączenie poprzedniego fragmentu kodu w pliku build.gradle lub build.gradle.kts modułu biblioteki, jeśli:

  • Testy z instrumentacją modułu biblioteki używają tych interfejsów API języka (bezpośrednio lub przez moduł biblioteki bądź jego zależności). Dzięki temu brakujące interfejsy API zostaną udostępnione w pliku APK testu z instrumentacją.

  • Chcesz uruchomić analizę kodu w module biblioteki w izolacji. Dzięki temu narzędzie lint może rozpoznawać prawidłowe zastosowania interfejsów API języka i unikać zgłaszania fałszywych ostrzeżeń.

Pamiętaj też, że odlukrzanie interfejsu API można połączyć ze zmniejszaniem, ale tylko wtedy, gdy używasz narzędzia do zmniejszania R8.

Wersje

W tabeli poniżej znajdziesz wersje biblioteki interfejsu API Java 8+ i minimalną wersję wtyczki Androida do obsługi Gradle, która obsługuje każdą z nich:

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-alpha10

Szczegółowe informacje o wersjach biblioteki interfejsu API Java 8+ znajdziesz w pliku CHANGELOG.md w repozytorium desugar_jdk_libs na GitHubie.