Szukaj…


Wprowadzenie

Android 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. Ta strona opisuje nowe funkcje językowe, których możesz użyć, jak poprawnie skonfigurować projekt, aby z nich korzystać oraz wszelkie znane problemy, które możesz napotkać.

Java 8 zawiera podzbiór w Retrolambda

Retrolambda pozwala uruchamiać kod Java 8 z wyrażeniami lambda, referencjami metod i instrukcjami try-with-resources w Javie 7, 6 lub 5. Robi to poprzez przekształcenie kodu bajtowego skompilowanego w Javie 8, tak aby mógł działać na starszym środowisku uruchomieniowym Java.

Funkcje językowe:

  • Wyrażenia lambda są przenoszone przez konwersję do anonimowych klas wewnętrznych. Obejmuje to optymalizację użycia instancji singleton dla bezstanowych wyrażeń lambda, aby uniknąć powtarzania alokacji obiektów. Odniesienia do metod są w zasadzie tylko cukrem składniowym dla wyrażeń lambda i są importowane w ten sam sposób.

  • Instrukcje try-with-resources są przenoszone z powrotem przez usunięcie wywołań do Throwable.addSuppressed jeśli docelowa wersja kodu bajtowego jest niższa niż Java 7. Jeśli chcesz, aby pominięte wyjątki były rejestrowane zamiast połykane, utwórz żądanie funkcji, a my to zrobimy konfigurowalny.

  • Objects.requireNonNull są zastępowane wywołaniami Object.getClass jeśli docelowa wersja kodu bajtowego jest poniżej Java 7. Syntetyczne kontrole zerowe generowane przez JDK 9 używają Objects.requireNonNull , podczas gdy wcześniejsze wersje JDK używały Object.getClass .

  • Opcjonalnie również:

    1. Metody domyślne są importowane przez kopiowanie metod domyślnych do klasy towarzyszącej (nazwa interfejsu + „$”) jako metody statyczne, zastępowanie metod domyślnych w interfejsie metodami abstrakcyjnymi oraz dodawanie niezbędnych implementacji metod do wszystkich klas, które implementują ten interfejs .

    2. Metody statyczne w interfejsach są importowane przez przeniesienie metod statycznych do klasy towarzyszącej (nazwa interfejsu + „$”) oraz przez zmianę wszystkich wywołań metod w celu wywołania nowej lokalizacji metody.

Znane ograniczenia:

  • Nie backportuje API Java 8

  • Domyślne metody tworzenia backportów i metody statyczne na interfejsach wymagają wszystkich backportowanych interfejsów i wszystkich klas, które je implementują lub wywołują swoje metody statyczne, aby były backportowane razem, z jednym wykonaniem Retrolambda. Innymi słowy, zawsze musisz wykonać czystą kompilację. Ponadto, domyślne metody backportowania nie będą działać ponad granicami modułu lub zależności.

  • Może się zepsuć, jeśli przyszła kompilacja JDK 8 przestanie generować nową klasę dla każdego invokedynamic połączenia invokedynamic . Retrolambda działa tak, że przechwytuje kod bajtowy generowany przez java.lang.invoke.LambdaMetafactory dynamicznie, więc optymalizacja tego mechanizmu może przerwać Retrolambda.

Wtyczka stopni Retrolambda automatycznie zbuduje twój projekt Androida z Retrolambda. Najnowsza wersja znajduje się na stronie wydań .

Stosowanie:

  1. Pobierz i zainstaluj jdk8
  2. Dodaj następujące elementy do swojego build.gradle
buildscript {
  repositories {
     mavenCentral()
  }

  dependencies {
     classpath 'me.tatarka:gradle-retrolambda:<latest version>'
  }
}

// Required because retrolambda is on maven central
repositories {
  mavenCentral()
}

apply plugin: 'com.android.application' //or apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

Znane problemy:

  • Lint nie działa na plikach Java, które mają lambdas. Strumień Androida nie rozumie składni java 8 i zawiedzie cicho lub głośno. Istnieje teraz eksperymentalny widelec, który rozwiązuje ten problem.

  • Korzystanie z usług Google Play powoduje awarię Retrolambda. Wersja 5.0.77 zawiera kod bajtowy, który jest niezgodny z Retrolambda. Powinno to zostać naprawione w nowszych wersjach usług odtwarzania, jeśli możesz je zaktualizować, powinno to być preferowane rozwiązanie. Aby obejść ten problem, możesz użyć wcześniejszej wersji, takiej jak 4.4.52, lub dodać -noverify do argumentów -noverify .

retrolambda {
  jvmArgs '-noverify'
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow