Versioni di Java nelle build di Android

Che il codice sorgente sia scritto in Java, Kotlin o entrambi, è necessario scegliere una versione in linguaggio JDK o Java per la build in diverse posizioni.

Panoramica delle relazioni JDK in una build Gradle

Glossario

Java Development Kit (JDK)
Il Java Development Kit (JDK) contiene:
  • Strumenti come compilatore, profiler e creatore di archivi. che vengono utilizzati dietro le quinte durante la build per creare l'applicazione.
  • Librerie contenenti API che puoi chiamare dal tuo codice sorgente Kotlin o Java. Tieni presente che non tutte le funzioni sono disponibili su Android.
  • La Java Virtual Machine (JVM), un interprete che esegue applicazioni Java. Puoi utilizzare la JVM per eseguire l'IDE di Android Studio e lo strumento di creazione Gradle. La JVM non viene utilizzata su emulatori o dispositivi Android.
Runtime JetBrains (JBR)
Il JetBrains Runtime (JBR) è un JDK avanzato, distribuito con Android Studio. Include diverse ottimizzazioni per l'utilizzo in Studio e nei prodotti JetBrains correlati, ma può essere utilizzato anche per eseguire altre applicazioni Java.

Come faccio a scegliere un JDK per eseguire Android Studio?

Ti consigliamo di usare JBR per eseguire Android Studio. Viene implementato e utilizzato per testare Android Studio e include miglioramenti per un utilizzo ottimale di Android Studio. Per farlo, non impostare la variabile di ambiente STUDIO_JDK.

Gli script di avvio per Android Studio cercano una JVM nel seguente ordine:

  1. STUDIO_JDK variabile di ambiente
  2. Directory studio.jdk (nella distribuzione di Android Studio)
  3. jbr (Runtime JetBrains), nella distribuzione Android Studio. Consigliati
  4. JDK_HOME variabile di ambiente
  5. JAVA_HOME variabile di ambiente
  6. java eseguibile nella variabile di ambiente PATH

Come faccio a scegliere quali JDK esegue le build Gradle?

Se esegui Gradle utilizzando i pulsanti in Android Studio, per eseguire Gradle viene utilizzato il JDK impostato nelle impostazioni di Android Studio. Se esegui Gradle in un terminale, all'interno o all'esterno di Android Studio, la variabile di ambiente JAVA_HOME (se impostata) determina quale JDK esegue gli script Gradle. Se JAVA_HOME non è impostato, utilizza il comando java sulla variabile di ambiente PATH.

Per ottenere risultati più coerenti, assicurati di impostare la variabile di ambiente JAVA_HOME e la configurazione di Gradle JDK in Android Studio sullo stesso JDK.

Durante l'esecuzione della build, Gradle crea un processo chiamato daemon per eseguire la build effettiva. Questo processo può essere riutilizzato, a condizione che le build utilizzino le stesse versioni di JDK e Gradle. Il riutilizzo di un daemon riduce il tempo necessario per avviare una nuova JVM e inizializzare il sistema di build.

Se avvii build con versioni JDK o Gradle diverse, vengono creati daemon aggiuntivi, che utilizzano più CPU e memoria.

Configurazione JDK Gradle in Android Studio

Per modificare la configurazione JDK Gradle del progetto esistente, apri le impostazioni di Gradle da File (o Android Studio su macOS) > Impostazioni > Crea, Esecuzione, Deployment > Strumenti di creazione > Gradle. Il menu a discesa Gradle JDK contiene le seguenti opzioni tra cui scegliere:

  • Macro come JAVA_HOME e GRADLE_LOCAL_JAVA_HOME
  • Le voci della tabella JDK in formato vendor-version, come jbr-17, che sono archiviate nei file di configurazione Android
  • Download di un file JDK
  • Aggiunta di un JDK specifico
  • JDK rilevati localmente dalla directory di installazione JDK predefinita del sistema operativo

L'opzione selezionata è archiviata nell'opzione gradleJvm del file .idea/gradle.xml del progetto e la sua risoluzione del percorso JDK viene utilizzata per eseguire Gradle quando viene avviato tramite Android Studio.

Figura 1. Impostazioni Gradle JDK in Android Studio.

Le macro consentono la selezione dinamica del percorso JDK del progetto:

  • JAVA_HOME: utilizza la variabile di ambiente con lo stesso nome
  • GRADLE_LOCAL_JAVA_HOME: utilizza la proprietà java.home nel file .gradle/config.properties che utilizza per impostazione predefinita il runtime JetBrains.

Il JDK selezionato viene utilizzato per eseguire la build Gradle e risolvere i riferimenti dell'API JDK quando modifichi gli script di build e il codice sorgente. Tieni presente che il valore compileSdk specificato limiterà ulteriormente i simboli Java che saranno disponibili durante la modifica e la creazione del codice sorgente.

Assicurati di scegliere una versione JDK superiore o uguale alle versioni JDK utilizzate dai plug-in che usi nella build Gradle. Per determinare la versione JDK minima richiesta per il plug-in Android Gradle (AGP), consulta la tabella di compatibilità nelle note di rilascio.

Ad esempio, il plug-in per Android Gradle versione 8.x richiede JDK 17. Se provi a eseguire una build Gradle che lo utilizza con una versione precedente del JDK, verrà segnalato un messaggio come:

An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
      Your current JDK is located in /usr/local/buildtools/java/jdk11
      You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.

Quali API Java posso utilizzare nel mio codice sorgente Java o Kotlin?

Un'applicazione Android può utilizzare alcune delle API definite in un JDK, ma non tutte. L'SDK Android definisce le implementazioni di molte funzioni di libreria Java come parte delle API disponibili. La proprietà compileSdk specifica la versione dell'SDK Android da utilizzare durante la compilazione del codice sorgente Kotlin o Java.

Kotlin

android {
    ...
    compileSdk = 33
}

trendy

android {
    ...
    compileSdk 33
}

Ogni versione di Android supporta una versione specifica di JDK e un sottoinsieme delle API Java disponibili. Se utilizzi un'API Java disponibile in un elemento compileSdk che non è disponibile in minSdk specificato, potresti riuscire a utilizzare l'API nella versione precedente di Android tramite una procedura nota come desugaring. Per le API supportate, consulta API Java 11 e versioni successive disponibili tramite desugaring.

Utilizza questa tabella per determinare quale versione di Java è supportata da ogni API Android e dove trovare i dettagli sulle API Java disponibili.

Android Java Funzionalità API e lingua supportate
14 (API 34) 17 Librerie di base
13 (API 33) 11 Librerie di base
12 (API 32) 11 API Java
11 e meno Versioni di Android

Quale JDK compila il mio codice sorgente Java?

Il JDK Java toolchain contiene il compilatore Java utilizzato per compilare qualsiasi codice sorgente Java. Questo JDK esegue anche javadoc e test delle unità durante la compilazione.

Per impostazione predefinita, la toolchain utilizza il JDK utilizzato per eseguire Gradle. Se utilizzi l'impostazione predefinita ed esegui una build su macchine diverse (ad esempio, la tua macchina locale e un server di integrazione continua separato), i risultati della build possono essere diversi se vengono utilizzate versioni JDK diverse.

Per creare una build più coerente, puoi specificare esplicitamente una versione della toolchain Java. Specifica:

  • Individua un JDK compatibile sul sistema che esegue la build.
    • Se non esiste un JDK compatibile (e viene definito un resolver toolchain), ne scarica uno.
  • Espone le API Java toolchain per le chiamate dal codice sorgente.
  • Compila il codice sorgente Java utilizzando la versione in linguaggio Java.
  • Fornisce impostazioni predefinite per sourceCompatibility e targetCompatibility.

Ti consigliamo di specificare sempre la toolchain Java e di assicurarti che il JDK specificato sia installato o di aggiungere un resolver toolchain alla build.

Puoi specificare la toolchain se il codice sorgente è scritto in Java, Kotlin o in entrambi. Specifica la toolchain al livello superiore del file build.gradle(.kts) del modulo.

Se il codice sorgente è scritto solo in Java, specifica la versione della toolchain Java in questo modo:

Kotlin

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

trendy

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

Se la tua origine è solo Kotlin o un mix di Kotlin e Java, specifica la versione della toolchain Java in questo modo:

Kotlin

kotlin {
    jvmToolchain(17)
}

trendy

kotlin {
    jvmToolchain 17
}

La versione JDK della toolchain può essere la stessa del JDK utilizzato per eseguire Gradle, ma tieni presente che hanno scopi diversi.

Quali funzionalità sorgente del linguaggio Java posso utilizzare nel mio codice sorgente Java?

La proprietà sourceCompatibility determina quali funzionalità del linguaggio Java sono disponibili durante la compilazione dell'origine Java. Non influisce sulla fonte Kotlin.

Se non specificato, per impostazione predefinita viene utilizzata la Toolchain Java o il JDK utilizzato per eseguire Gradle. Ti consigliamo di specificare sempre esplicitamente una toolchain (preferita) o sourceCompatibility.

Specifica sourceCompatibility nel file build.gradle(.kts) del modulo.

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

trendy

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

Quali caratteristiche binarie di Java possono essere utilizzate durante la compilazione del mio codice sorgente Kotlin o Java?

Specificando targetCompatibility e jvmTarget si determina la versione nel formato di classe Java utilizzata durante la generazione di bytecode per l'origine Java compilata e Kotlin, rispettivamente.

Alcune funzionalità di Kotlin esistevano prima dell'aggiunta di funzionalità Java equivalenti. I primi compilatori Kotlin dovevano creare un modo personalizzato per rappresentare queste caratteristiche di Kotlin. Alcune di queste funzionalità sono state successivamente aggiunte a Java. Con i livelli jvmTarget successivi, il compilatore Kotlin potrebbe utilizzare direttamente la funzionalità Java, il che potrebbe migliorare le prestazioni.

Per impostazione predefinita, il valore di targetCompatibility corrisponde a sourceCompatibility, ma se specificato deve essere maggiore o uguale a sourceCompatibility.

jvmTarget utilizza come impostazione predefinita la versione toolchain.

Le varie versioni di Android supportano versioni diverse di Java. Puoi sfruttare le funzionalità Java aggiuntive aumentando targetCompatibility e jvmTarget, ma questo potrebbe costringerti ad aumentare anche la versione minima dell'SDK Android per assicurarti che la funzionalità sia disponibile.

Kotlin

android {
    compileOptions {
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

trendy

android {
    compileOptions {
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget '17'
    }
}