Android
Java su Android
Ricerca…
introduzione
Android supporta tutte le funzionalità del linguaggio Java 7 e un sottoinsieme di funzionalità del linguaggio Java 8 che variano in base alla versione della piattaforma. Questa pagina descrive le nuove funzionalità linguistiche che puoi utilizzare, come configurare correttamente il tuo progetto per usarle e tutti i problemi noti che potresti incontrare.
Funzionalità Java 8 sottoinsiemi con Retrolambda
Retrolambda consente di eseguire codice Java 8 con espressioni lambda, riferimenti al metodo e istruzioni try-with-resources su Java 7, 6 o 5. Lo fa trasformando il codice byte di Java 8 compilato in modo che possa essere eseguito su un runtime Java precedente.
Funzionalità della lingua backport:
Le espressioni lambda sono supportate convertendole in classi interne anonime. Ciò include l'ottimizzazione dell'utilizzo di un'istanza singleton per espressioni lambda stateless per evitare l'allocazione ripetuta degli oggetti. I riferimenti al metodo sono fondamentalmente solo lo zucchero di sintassi per le espressioni lambda e vengono backportati allo stesso modo.
Le istruzioni Try-with-resources vengono
Throwable.addSuppressed
rimuovendo le chiamate aThrowable.addSuppressed
se la versione bytecode di destinazione è inferiore a Java 7. Se si desidera che le eccezioni soppresse vengano registrate anziché ingerite, si prega di creare una richiesta di funzionalità e la faremo configurabile.Objects.requireNonNull
chiamateObjects.requireNonNull
vengono sostituite con chiamate aObject.getClass
se la versione bytecode di destinazione è inferiore a Java 7. I controlli Null sintetici generati da JDK 9 utilizzanoObjects.requireNonNull
, mentre le versioni precedenti di JDK utilizzavanoObject.getClass
.Opzionalmente anche:
I metodi predefiniti vengono sottoposti a backport copiando i metodi predefiniti in una classe companion (nome interfaccia + "$") come metodi statici, sostituendo i metodi predefiniti nell'interfaccia con metodi astratti e aggiungendo le implementazioni del metodo necessarie a tutte le classi che implementano tale interfaccia .
I metodi statici sulle interfacce vengono sottoposti a backport spostando i metodi statici in una classe companion (nome dell'interfaccia + "$") e cambiando tutte le chiamate di metodi per chiamare il nuovo percorso del metodo.
Limiti noti:
Non esegue il backport delle API Java 8
I metodi di backporting predefiniti e i metodi statici sulle interfacce richiedono tutte le interfacce backported e tutte le classi che li implementano o richiamano i loro metodi statici per il backporting insieme, con un'esecuzione di Retrolambda. In altre parole, devi sempre fare una build pulita. Inoltre, i metodi predefiniti per il backport non funzioneranno tra i limiti del modulo o delle dipendenze.
Può interrompersi se un futuro build JDK 8 interrompe la generazione di una nuova classe per ogni chiamata ad
invokedynamic
. Retrolambda funziona in modo da catturare il bytecode generato dajava.lang.invoke.LambdaMetafactory
modo dinamico, quindi le ottimizzazioni a tale meccanismo potrebbero interrompere Retrolambda.
Retrolambda gradle plugin creerà automaticamente il tuo progetto Android con Retrolambda. L'ultima versione può essere trovata nella pagina dei rilasci .
Uso:
- Scarica e installa jdk8
- Aggiungi quanto segue al tuo
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
}
}
Problemi noti:
Lint non funziona sui file java con lambda. La lanugine di Android non capisce la sintassi di java 8 e fallirà silenziosamente o ad alta voce. Ora c'è un fork sperimentale che risolve il problema.
L'utilizzo di Google Play Services causa il fallimento di Retrolambda. La versione 5.0.77 contiene il bytecode incompatibile con Retrolambda. Questo dovrebbe essere risolto nelle versioni più recenti dei servizi di gioco, se è possibile aggiornare, questa dovrebbe essere la soluzione preferita. Per ovviare a questo problema, è possibile utilizzare una versione precedente come 4.4.52 o aggiungere
-noverify
agli-noverify
di jvm.
retrolambda {
jvmArgs '-noverify'
}