Android
Java på Android
Sök…
Introduktion
Android stöder alla Java 7-språkfunktioner och en delmängd av Java 8-språkfunktioner som varierar beroende på plattformsversion. Den här sidan beskriver de nya språkfunktionerna du kan använda, hur du konfigurerar projektet korrekt för att använda dem och alla kända problem du kan stöta på.
Java 8 har delmängd med Retrolambda
Med Retrolambda kan du köra Java 8-kod med lambda-uttryck, metodreferenser och försök med resurser-uttalanden på Java 7, 6 eller 5. Det gör detta genom att transformera din Java 8-kompilerade bytkod så att den kan köras på en äldre Java-runtime.
Backported-språkfunktioner:
Lambda-uttryck backporteras genom att konvertera dem till anonyma inre klasser. Detta inkluderar optimering av att använda en singleton-instans för statslösa lambda-uttryck för att undvika upprepad objektallokering. Metodreferenser är i princip bara syntaxsocker för lambda-uttryck och de återporteras på samma sätt.
Try-with-resources-uttalanden backporteras genom att ta bort samtal till
Throwable.addSuppressed
om målbytekodversionen är under Java 7. Om du vill att de undertryckta undantagen ska loggas istället för att sväljas, vänligen skapa en funktionsbegäran så gör vi det konfigurerbar.Objects.requireNonNull
samtal ersätts med samtal tillObject.getClass
om målbytekodversionen är under Java 7. De syntetiska nollkontroller som genereras av JDK 9 använderObjects.requireNonNull
, medan tidigare JDK-versioner användeObject.getClass
.Eventuellt också:
Standardmetoder backporteras genom att kopiera standardmetoderna till en följeslagarklass (gränssnittsnamn + "$") som statiska metoder, ersätta standardmetoderna i gränssnittet med abstrakta metoder och genom att lägga till nödvändiga metodimplementeringar till alla klasser som implementerar det gränssnittet .
Statiska metoder på gränssnitt backporteras genom att flytta de statiska metoderna till en följeslagarklass (gränssnittsnamn + "$") och genom att ändra alla metoders samtal för att anropa den nya metodplatsen.
Kända begränsningar:
Backportar inte Java 8 API: er
Backporting standardmetoder och statiska metoder på gränssnitt kräver alla backported gränssnitt och alla klasser som implementerar dem eller kallar deras statiska metoder för att backporteras tillsammans, med en exekvering av Retrolambda. Med andra ord måste du alltid göra en ren byggnad. Dessutom fungerar inte backporting av standardmetoder över modul- eller beroendegränser.
Kan bryta om en framtida JDK 8-konstruktion slutar generera en ny klass för varje
invokedynamic
samtal. Retrolambda fungerar så att den fångar bytkoden somjava.lang.invoke.LambdaMetafactory
genererar dynamiskt, så optimeringar av den mekanismen kan bryta Retrolambda.
Retrolambda gradle plugin kommer automatiskt att bygga ditt Android-projekt med Retrolambda. Den senaste versionen finns på utgivarsidan .
Användande:
- Ladda ner och installera jdk8
- Lägg till följande i din
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
}
}
Kända problem:
Luddet misslyckas med java-filer som har lambdas. Androids ludd förstår inte syntaxen för Java 8 och kommer att tystas eller högt. Det finns nu en experimentell gaffel som löser problemet.
Att använda Google Play Services får Retrolambda att misslyckas. Version 5.0.77 innehåller bytekod som inte är kompatibel med Retrolambda. Detta bör fixas i nyare versioner av speltjänster, om du kan uppdatera, borde det vara den föredragna lösningen. För att lösa problemet kan du antingen använda en tidigare version som 4.4.52 eller lägga till
-noverify
till jvm args.
retrolambda {
jvmArgs '-noverify'
}