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 a Throwable.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 chiamate Objects.requireNonNull vengono sostituite con chiamate a Object.getClass se la versione bytecode di destinazione è inferiore a Java 7. I controlli Null sintetici generati da JDK 9 utilizzano Objects.requireNonNull , mentre le versioni precedenti di JDK utilizzavano Object.getClass .

  • Opzionalmente anche:

    1. 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 .

    2. 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 da java.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:

  1. Scarica e installa jdk8
  2. 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'
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow