Zoeken…


Invoering

Android ondersteunt alle Java 7-taalfuncties en een subset van Java 8-taalfuncties die verschillen per platformversie. Deze pagina beschrijft de nieuwe taalfuncties die u kunt gebruiken, hoe u uw project correct configureert om ze te gebruiken en bekende problemen die u kunt tegenkomen.

Java 8 functies subset met Retrolambda

Met Retrolambda kunt u Java 8-code uitvoeren met lambda-expressies, methodeverwijzingen en try-with-resources-instructies op Java 7, 6 of 5. Het doet dit door uw door Java 8 gecompileerde bytecode te transformeren zodat deze op een oudere Java-runtime kan worden uitgevoerd.

Backported taalfuncties:

  • Lambda-uitdrukkingen worden teruggebracht door ze om te zetten in anonieme binnenklassen. Dit omvat de optimalisatie van het gebruik van een singleton-instantie voor stateloze lambda-expressies om herhaalde objecttoewijzing te voorkomen. Referentiemethoden zijn in feite gewoon syntaxisuiker voor lambda-expressies en ze worden op dezelfde manier teruggezet.

  • Try-with-resources-instructies worden teruggezet door aanroepen van Throwable.addSuppressed te Throwable.addSuppressed als de bytecodeversie van het doel lager is dan Java 7. Als u wilt dat de onderdrukte uitzonderingen worden vastgelegd in plaats van ingeslikt, maakt u een functieverzoek en maken we het configureerbare.

  • Objects.requireNonNull aanroepen worden vervangen door aanroepen naar Object.getClass als de Object.getClass lager is dan Java 7. De synthetische null-controles gegenereerd door JDK 9 gebruiken Objects.requireNonNull , terwijl eerdere JDK-versies Object.getClass gebruikten.

  • Optioneel ook:

    1. Standaardmethoden worden teruggezet door de standaardmethoden naar een begeleidende klasse (interfacenaam + "$") te kopiëren als statische methoden, de standaardmethoden in de interface te vervangen door abstracte methoden en door de benodigde methode-implementaties toe te voegen aan alle klassen die die interface implementeren .

    2. Statische methoden op interfaces worden teruggezet door de statische methoden te verplaatsen naar een begeleidende klasse (interfacenaam + "$") en door alle methodeaanroepen te wijzigen om de nieuwe methodelocatie aan te roepen.

Bekende beperkingen:

  • Geen backport van Java 8 API's

  • Voor het backporten van standaardmethoden en statische methoden op interfaces zijn alle backported interfaces en alle klassen die deze implementeren of hun statische methoden aanroepen, samen backported, met één uitvoering van Retrolambda. Met andere woorden, je moet altijd een schone build uitvoeren. Backporting van standaardmethoden werkt ook niet over module- of afhankelijkheidsgrenzen heen.

  • Kan breken als een toekomstige JDK 8-build stopt met het genereren van een nieuwe klasse voor elke invokedynamic aanroep. Retrolambda werkt zodanig dat het de bytecode vangt die java.lang.invoke.LambdaMetafactory dynamisch genereert, dus optimalisaties van dat mechanisme kunnen Retrolambda breken.

Retrolambda gradle plug- in bouwt automatisch je Android-project met Retrolambda. De nieuwste versie is te vinden op de releasepagina .

Gebruik:

  1. Download en installeer jdk8
  2. Voeg het volgende toe aan uw 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
    }
}

Bekende problemen:

  • Lint mislukt op java-bestanden met lambdas. Android's lint begrijpt de syntaxis van Java 8 niet en zal stil of luid falen. Er is nu een experimentele vork die het probleem oplost.

  • Het gebruik van Google Play Services zorgt ervoor dat Retrolambda mislukt. Versie 5.0.77 bevat bytecode die niet compatibel is met Retrolambda. Dit moet worden opgelost in nieuwere versies van play-services, als u kunt updaten, zou dat de voorkeursoplossing moeten zijn. U kunt dit probleem omzeilen door een eerdere versie zoals 4.4.52 te gebruiken of -noverify te voegen aan de jvm-args.

retrolambda {
  jvmArgs '-noverify'
}


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow