Usar recursos da linguagem Java 8

O Android Studio 3.0 e versões mais recentes é compatível com todos os recursos da linguagem Java 7 e com um subconjunto de recursos da linguagem Java 8, que variam de acordo com a versão da plataforma. Esta página descreve os recursos da linguagem Java 8 que você pode usar, como configurar seu projeto adequadamente para usá-los e possíveis problemas conhecidos. Para ter uma visão geral, assista também o vídeo a seguir.

Observação: o uso de recursos da linguagem Java 8 é opcional no desenvolvimento de apps para Android. Você pode manter os valores de compatibilidade de origem e destino definidos como Java 7, mas ainda será necessário compilar usando o JDK 8.

O Android Studio é compatível com alguns recursos da linguagem Java 8 e com algumas bibliotecas de terceiros que os utilizam. Como mostrado na Figura 1, o conjunto de ferramentas padrão implementa os novos recursos da linguagem executando transformações de bytecode, denominadas desugar, na saída do compilador javac. O Jack não é mais compatível, e é necessário desativá-lo para usar a compatibilidade integrada com o Java 8 no conjunto de ferramentas padrão.

Figura 1. Compatibilidade com recursos da linguagem Java 8 usando transformações de bytecode desugar.

Para começar a usar os recursos da linguagem Java 8 compatíveis, atualize o plug-in do Android para a versão 3.0.0 (ou mais recente). Em seguida, para cada módulo que usa os recursos da linguagem Java 8 (no código-fonte ou nas dependências), atualize as opções Source Compatibility e Target Compatibility para 1.8 na caixa de diálogo Project Structure, conforme mostrado na Figura 2 (clique em File > Project Structure).

Figura 2. Compatibilidade com recursos da linguagem Java 8 usando transformações de bytecode desugar.

Você também pode fazer a configuração diretamente no arquivo build.gradle correspondente:

android {
      ...
      // Configure only for each module that uses Java 8
      // language features (either in its source code or
      // through dependencies).
      compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
      }
      // For Kotlin projects
      kotlinOptions {
        jvmTarget = "1.8"
      }
    }
    

Observação: se o Android Studio detectar que o projeto está usando o Jack, Retrolambda ou DexGuard (links em inglês), o ambiente de desenvolvimento integrado usará a compatibilidade com o Java 8 oferecida por essas ferramentas. No entanto, é recomendado migrar para o conjunto de ferramentas padrão.

Recursos e APIs compatíveis com a linguagem Java 8

O Android Studio não é compatível com todos os recursos da linguagem Java 8, mas essa compatibilidade está sendo ampliada em versões futuras do ambiente de desenvolvimento integrado. Dependendo da minSdkVersion usada, alguns recursos e APIs já estão disponíveis, conforme descrito na tabela abaixo.

Recurso da linguagem Java 8 minSdkVersion compatível
Expressões lambda Todas. O Android não é compatível com a serialização de expressões lambda.
Referências de métodos (link em inglês) Todas.
Anotações de tipo (link em inglês) Todas. No entanto, as informações de anotação de tipo estão disponíveis no momento da compilação, e não no da execução. Além disso, a plataforma é compatível com TYPE na API de nível 24 ou anterior, mas não é compatível com ElementType.TYPE_USE ou ElementType.TYPE_PARAMETER.
Métodos de interface padrão e estáticos (link em inglês) Todas.
Repetição de anotações (link em inglês) Todas.
API da linguagem Java 8 minSdkVersion compatível
java.lang.annotation.Repeatable API de nível 24 ou mais recente.
AnnotatedElement.getAnnotationsByType(Class) API de nível 24 ou mais recente.
java.util.stream API de nível 24 ou mais recente.
java.lang.FunctionalInterface API de nível 24 ou mais recente.
java.lang.reflect.Method.isDefault() API de nível 24 ou mais recente.
java.util.function API de nível 24 ou mais recente.

Além dos recursos e APIs da linguagem Java 8 descritos acima, o Android Studio 3.0 e versões mais recentes ampliam a compatibilidade com try-with-resources (link em inglês) para todos os níveis de API do Android.

No momento, desugar não é compatível com MethodHandle.invoke ou MethodHandle.invokeExact (links em inglês). Se o código-fonte ou uma das dependências do módulo usar um desses métodos, será necessário especificar minSdkVersion 26 ou versão mais recente. Caso contrário, ocorrerá o seguinte erro:

Dex: Error converting bytecode to dex:
    Cause: signature-polymorphic method called without --min-sdk-version >= 26
    

Em alguns casos, pode ocorrer que o módulo não use os métodos invoke ou invokeExact, mesmo se incluídos em uma dependência de biblioteca. Portanto, para continuar usando essa biblioteca com minSdkVersion 25 ou versões anteriores, ative a redução de código e remova os métodos não usados. Se isso não funcionar, use outra biblioteca que não utilize os métodos incompatíveis.

Migrar para o conjunto de ferramentas padrão

Se o Android Studio detectar que o projeto está usando Jack, Retrolambda ou DexGuard, o ambiente de desenvolvimento integrado usará a compatibilidade com o Java 8 oferecida por essas ferramentas. No entanto, em comparação com o conjunto de ferramentas padrão, faltam a essas ferramentas algumas funcionalidades e compatibilidade. Portanto, siga as instruções desta seção para migrar para o conjunto de ferramentas padrão do Android Studio.

Migrar do Jack

O conjunto de ferramentas Jack está obsoleto, de acordo com este anúncio (em inglês). Se o projeto depender do Jack, faça a migração usando a compatibilidade com o Java 8 incorporada ao conjunto de ferramentas padrão do Android Studio. O uso do conjunto de ferramentas padrão também oferece compatibilidade com bibliotecas de terceiros que usam recursos da linguagem Java 8 e ferramentas que dependem de arquivos .class intermediários.

Para desativar o Jack e mudar para o conjunto de ferramentas padrão, basta remover o bloco jackOptions do arquivo build.gradle do módulo:

android {
        ...
        defaultConfig {
            ...
            // Remove this block.
            jackOptions {
                enabled true
                ...
            }
        }

        // Keep the following configuration in order to target Java 8.
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        // For Kotlin projects
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
    

Migrar do Retrolambda

Em comparação com o conjunto de ferramentas padrão do Android Studio, o Retrolambda não é compatível com bibliotecas de terceiros que usam recursos da linguagem Java 8. Para migrar para o conjunto de ferramentas padrão, remova a dependência do Retrolambda do arquivo build.gradle do projeto:

buildscript {
      ...
       dependencies {
          // Remove the following dependency.
          classpath 'me.tatarka:gradle-retrolambda:<version_number>'
       }
    }
    

Além disso, remova o plug-in do Retrolambda e o bloco retrolambda do arquivo build.gradle de cada módulo:

    // Remove the following plugin.
    apply plugin: 'me.tatarka.retrolambda'
    ...
    // Remove this block after migrating useful configurations.
    retrolambda {
        ...
        // If you have arguments for the Java VM you want to keep,
        // move them to your project's gradle.properties file.
        jvmArgs '-Xmx2048m'
    }
    

Desativar compatibilidade com recursos da linguagem Java 8

Se você tiver problemas relacionados à compatibilidade com recursos da linguagem Java 8, poderá desativar essa compatibilidade adicionando o seguinte ao arquivo gradle.properties:

android.enableDesugar=false
    

Para nos ajudar a melhorar a compatibilidade com o Java 8, informe um bug.