Versões Java em builds do Android

Se o código-fonte foi escrito em Java, Kotlin ou ambos, há vários lugares em que você precisa escolher uma versão do JDK ou da linguagem Java para o build.

Visão geral das relações do JDK em um build do Gradle
Figura 1. Relações do JDK em um build

Glossário

Kit de desenvolvimento Java (JDK)
O Kit de desenvolvimento Java (JDK) contém:
  • Ferramentas, como um compilador, um criador de perfil e um criador de arquivos. Elas são usadas nos bastidores durante o build para criar o aplicativo.
  • Bibliotecas que contêm APIs que podem ser chamadas do código-fonte Kotlin ou Java. Nem todas as funções estão disponíveis no Android.
  • A Java Virtual Machine (JVM), um interpretador que executa aplicativos Java. Você usa a JVM para executar o ambiente de desenvolvimento integrado do Android Studio e a ferramenta de build do Gradle. A JVM não é usada em dispositivos ou emuladores Android.
Ambiente de execução JetBrains (JBR)
O ambiente de execução JetBrains (JBR) é um JDK aprimorado, distribuído com o Android Studio. Ele inclui várias otimizações para uso no Studio e em produtos relacionados do JetBrains produtos, mas também pode ser usado para executar outros aplicativos Java.

Como escolho um JDK para executar o Android Studio?

Recomendamos o uso do JBR para executar o Android Studio. Ele é implantado e usado para testar o Android Studio e inclui melhorias para o uso ideal do Android Studio. Para garantir isso, não defina a variável de ambiente STUDIO_JDK.

Os scripts de inicialização do Android Studio procuram uma JVM nesta ordem:

  1. Variável de ambiente STUDIO_JDK
  2. Diretório studio.jdk (na distribuição do Android Studio)
  3. Diretório jbr (ambiente de execução JetBrains), na distribuição do Android Studio. Recomendado.
  4. Variável de ambiente JDK_HOME
  5. Variável de ambiente JAVA_HOME
  6. Executável java na variável de ambiente PATH

Como escolho qual JDK executa meus builds do Gradle?

Se você executar o Gradle usando os botões no Android Studio, o JDK definido nas configurações do Android Studio será usado para executar o Gradle. Se você executar o Gradle em um terminal, dentro ou fora do Android Studio, a variável de ambiente JAVA_HOME (se definida) determinará qual JDK executa os scripts do Gradle. Se JAVA_HOME não estiver definido, ele usará o comando java na variável de ambiente PATH.

Para resultados mais consistentes, defina sua JAVA_HOME variável de ambiente e a configuração do JDK do Gradle no Android Studio para o mesmo JDK.

Ao executar o build, o Gradle cria um processo chamado daemon para realizar o build real. Esse processo pode ser reutilizado, desde que os builds usem a mesma versão do JDK e do Gradle. A reutilização de um daemon reduz o tempo para iniciar uma nova JVM e inicializar o sistema de build.

Se você iniciar builds com diferentes JDKs ou versões do Gradle, outros daemons serão criados, consumindo mais CPU e memória.

Configuração do JDK do Gradle no Android Studio

Para modificar a configuração do JDK do Gradle do projeto atual, abra as configurações do Gradle em File (ou Android Studio no macOS) > Settings > Build, Execution, Deployment > Build Tools > Gradle. O menu suspenso Gradle JDK contém as seguintes opções para selecionar:

  • Macros como JAVA_HOME e GRADLE_LOCAL_JAVA_HOME
  • Entradas da tabela JDK no formato vendor-version, como jbr-17, que são armazenadas nos arquivos de configuração do Android
  • Como baixar um JDK
  • Como adicionar um JDK específico
  • JDKs detectados localmente no diretório de instalação padrão do JDK do sistema operacional

A opção selecionada é armazenada na opção gradleJvm no arquivo .idea/gradle.xml do projeto, e a resolução do caminho do JDK é usada para executar o Gradle quando iniciado pelo Android Studio.

Figura 2. Configurações do JDK do Gradle no Android Studio.

As macros permitem a seleção dinâmica do caminho do JDK do projeto:

  • JAVA_HOME: usa a variável de ambiente com o mesmo nome
  • GRADLE_LOCAL_JAVA_HOME: usa a propriedade java.home no arquivo .gradle/config.properties, que é padrão para o ambiente de execução JetBrains.

O JDK selecionado é usado para executar o build do Gradle e resolver referências de API do JDK ao editar scripts de build e código-fonte. O compileSdk especificado vai restringir ainda mais quais símbolos Java estarão disponíveis ao editar e criar o código-fonte.

Escolha uma versão do JDK que seja maior ou igual às versões do JDK usadas pelos plug-ins no build do Gradle. Para determinar a versão mínima necessária do JDK para o Plug-in do Android para Gradle (AGP), consulte a tabela de compatibilidade nas notas da versão.

Por exemplo, a versão 8.x do Plug-in do Android para Gradle requer o JDK 17. Se você tentar executar um build do Gradle que o use com uma versão anterior do JDK, ele vai informar uma mensagem como esta:

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/jdk
      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`.

Quais APIs Java posso usar no meu código-fonte Java ou Kotlin?

Um app Android pode usar algumas das APIs definidas em um JDK, mas não todas. O SDK do Android define implementações de muitas funções da biblioteca Java como parte das APIs disponíveis. A propriedade compileSdk especifica qual versão do SDK do Android usar ao compilar o código-fonte Kotlin ou Java.

Kotlin

android {
    ...
    compileSdk = 36
}

Groovy

android {
    ...
    compileSdk 36
}

Cada versão do Android oferece suporte a uma versão específica do JDK e a um subconjunto das APIs Java disponíveis. Se você usar uma API Java disponível em um compileSdk que não está disponível no minSdk especificado, poderá usar a API na versão anterior do Android por meio de um processo conhecido como simplificação. Consulte APIs Java 11+ disponíveis pela simplificação para APIs com suporte.

Use esta tabela para determinar qual versão do Java é compatível com cada API Android e onde encontrar detalhes sobre quais APIs Java estão disponíveis.

Android Java Recursos de API e linguagem com suporte
14 (API 34) 17 Bibliotecas principais
13 (API 33) 11 Bibliotecas principais
12 (API 32) 11 API Java
11 e versões anteriores Versões do Android

Qual JDK compila meu código-fonte Java?

O JDK da cadeia de ferramentas Java contém o compilador Java usado para compilar qualquer código-fonte Java. Esse JDK também executa javadoc e testes de unidade durante o build.

O conjunto de ferramentas é padrão para o JDK usado para executar o Gradle. Se você usar o padrão e executar um build em máquinas diferentes (por exemplo, sua máquina local e um servidor de integração contínua separado), os resultados do build poderão ser diferentes se versões diferentes do JDK forem usadas.

Para criar um build mais consistente, você pode especificar explicitamente uma versão da cadeia de ferramentas Java. Especificar isso:

  • Localiza um JDK compatível no sistema que executa o build.
    • Se nenhum JDK compatível existir (e um resolvedor de conjunto de ferramentas estiver definido), faça o download de um.
  • Expõe as APIs Java da cadeia de ferramentas para chamadas do código-fonte.
  • Compila a origem Java usando a versão da linguagem Java.
  • Fornece padrões para sourceCompatibility e targetCompatibility.

Recomendamos que você sempre especifique o conjunto de ferramentas Java e garanta que o JDK especificado esteja instalado ou adicione um resolvedor de cadeia de ferramentas ao build.

Você pode especificar a cadeia de ferramentas se o código-fonte for escrito em Java, Kotlin ou ambos. Especifique o conjunto de ferramentas no nível superior do arquivo build.gradle(.kts) do módulo.

Especifique a versão da cadeia de ferramentas Java desta forma:

Kotlin

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

Groovy

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

Isso funciona se a origem for Kotlin, Java ou uma combinação de ambos.

A versão do JDK do conjunto de ferramentas pode ser a mesma do JDK usado para executar o Gradle, mas lembre-se de que elas têm finalidades diferentes.

Quais recursos de origem da linguagem Java posso usar no meu código-fonte Java?

A propriedade sourceCompatibility determina quais recursos da linguagem Java estão disponíveis durante a compilação da origem Java. Ela não afeta a origem Kotlin.

Especifique sourceCompatibility no arquivo build.gradle(.kts) do módulo da seguinte maneira:

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

Groovy

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

Se não for especificada, essa propriedade será padrão para a versão do conjunto de ferramentas Java. Se você não estiver usando um conjunto de ferramentas Java, ela será padrão para uma versão escolhida pelo Plug-in do Android para Gradle (por exemplo, Java 8 ou mais recente).

Quais recursos binários Java podem ser usados ao compilar minha origem Kotlin ou Java?

As propriedades targetCompatibility e jvmTarget determinam a versão do formato de classe Java usada ao gerar bytecode para a origem Java e Kotlin compilada, respectivamente.

Alguns recursos do Kotlin existiam antes que recursos Java equivalentes fossem adicionados. Os primeiros compiladores Kotlin precisavam criar sua própria maneira de representar esses recursos do Kotlin. Alguns desses recursos foram adicionados ao Java mais tarde. Com níveis jvmTarget mais recentes, o compilador Kotlin pode usar diretamente o recurso Java, o que pode resultar em melhor desempenho.

Versões diferentes do Android oferecem suporte a versões diferentes do Java. Você pode aproveitar outros recursos Java aumentando targetCompatibility e jvmTarget, mas isso pode forçar você a também aumentar sua versão mínima do SDK do Android para garantir que o recurso esteja disponível.

Observe que targetCompatibility precisa ser maior ou igual a sourceCompatibility. Na prática, sourceCompatibility, targetCompatibility e jvmTarget geralmente usam o mesmo valor. É possível defini-los da seguinte maneira:

Kotlin

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

Groovy

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

Se não forem especificadas, essas propriedades serão padrão para a cadeia de ferramentas Java versão. Se você não estiver usando uma cadeia de ferramentas Java, os valores padrão poderão ser diferentes e causar problemas de build. Portanto, recomendamos que você sempre especifique esses valores explicitamente ou use uma cadeia de ferramentas Java.