Versões Java em builds do Android

Se o código-fonte estiver 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 para Java (JDK) contém:
  • Ferramentas, como um compilador, um criador de perfil e um criador de arquivos. Eles são usados nos bastidores durante o build para criar o aplicativo.
  • Bibliotecas que contêm APIs que podem ser chamadas no seu código-fonte Kotlin ou Java. Nem todas as funções estão disponíveis no Android.
  • A máquina virtual Java (JVM), um interpretador que executa aplicativos Java. Use 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 do 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 da JetBrains, mas também pode ser usado para executar outros aplicativos Java.

Como escolher um JDK para executar o Android Studio?

Recomendamos que você use o JBR para executar o Android Studio. Ele é implantado com o Android Studio e usado para testá-lo, além de incluir melhorias para otimizar o uso 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 na seguinte ordem:

  1. Por meio da 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. Por meio da variável de ambiente JDK_HOME.
  5. Por meio da variável de ambiente JAVA_HOME.
  6. Executável java na variável de ambiente PATH

Como escolher 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, seja dentro ou fora do Android Studio, a variável de ambiente JAVA_HOME (se definida) vai 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 a variável de ambiente JAVA_HOME 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 as mesmas versões 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 Gradle JDK do projeto, 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:

  • Macros como JAVA_HOME e GRADLE_LOCAL_JAVA_HOME
  • Entradas da tabela do JDK no formato vendor-version, como jbr-17, que são armazenadas nos arquivos de configuração do Android.
  • Como fazer o download de um JDK
  • 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 Gradle JDK 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 usa o ambiente de execução do JetBrains como padrão.

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

Escolha uma versão do JDK que seja maior ou igual às versões do JDK usadas pelos plug-ins na sua 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, o Plug-in do Android para Gradle versão 8.x requer o JDK 17. Se você tentar executar um build do Gradle que o use com uma versão anterior do JDK, uma mensagem como esta será mostrada:

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 de biblioteca Java como parte das APIs disponíveis. A propriedade compileSdk especifica qual versão do SDK do Android será usada ao compilar o código-fonte em Kotlin ou Java.

Kotlin

android {
    ...
    compileSdk = 36
}

Groovy

android {
    ...
    compileSdk 36
}

Cada versão do Android é compatível com uma versão específica do JDK e 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, talvez seja possível usar a API na versão anterior do Android por um processo conhecido como simplificação. Consulte as APIs Java 11+ disponíveis pela simplificação para ver as APIs compatíveis.

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

Android Java Recursos de API e linguagem compatíveis
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 do conjunto de ferramentas Java contém o compilador Java usado para compilar qualquer código-fonte Java. Esse JDK também executa o javadoc e os testes de unidade durante o build.

O conjunto de ferramentas usa como padrão 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 podem ser diferentes se forem usadas versões diferentes do JDK.

Para criar um build mais consistente, especifique explicitamente uma versão do conjunto de ferramentas do Java. Especificar isso:

  • Localiza um JDK compatível no sistema que executa o build.
    • Se não houver um JDK compatível (e um resolvedor de conjunto de ferramentas estiver definido), faz o download de um.
  • Expõe as APIs Java do conjunto de ferramentas para chamadas do código-fonte.
  • Compila a origem do 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 verifique se o JDK especificado está instalado ou adicione um resolvedor de conjunto de ferramentas ao build.

É possível especificar o conjunto de ferramentas se o código-fonte estiver 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 do conjunto de ferramentas do 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 dos dois.

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

Quais recursos 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 do 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 vai usar como padrão a versão do conjunto de ferramentas do Java. Se você não estiver usando um conjunto de ferramentas Java, o padrão será uma versão escolhida pelo Plug-in do Android para Gradle (por exemplo, Java 8 ou mais recente).

Quais recursos binários do Java podem ser usados quando eu compilo minha origem Kotlin ou Java?

A propriedade targetCompatibility determina a versão do formato de classe Java usada ao gerar bytecode para fontes Java e Kotlin compiladas, respectivamente.

Alguns recursos do Kotlin já existiam antes da adição de recursos equivalentes do Java. Os primeiros compiladores do Kotlin precisavam criar uma maneira própria de representar esses recursos do Kotlin. Alguns desses recursos foram adicionados ao Java posteriormente. Com níveis mais recentes de targetCompatibility, o compilador Kotlin pode usar diretamente o recurso Java, o que pode resultar em uma performance melhor.

Versões diferentes do Android são compatíveis com versões diferentes do Java. É possível aproveitar outros recursos do Java aumentando targetCompatibility, mas isso pode forçar você a também aumentar a versão mínima do SDK do Android para garantir que o recurso esteja disponível.

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

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}

Groovy

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
}

Se você estiver usando uma versão do Kotlin anterior à 2.2, também será necessário definir kotlinOptions:

Kotlin

android {
    kotlinOptions {
        jvmTarget = "17"
    }
}

Groovy

android {
    kotlinOptions {
        jvmTarget = "17"
    }
}

Se não forem especificadas, essas propriedades vão usar como padrão a versão do conjunto de ferramentas do Java. Se você não estiver usando um conjunto de ferramentas Java, os valores padrão podem ser diferentes e causar problemas de build. Portanto, recomendamos que você sempre especifique esses valores de forma explícita ou use um conjunto de ferramentas Java.