Usar recursos da linguagem Java 8

O Android Studio 3.0 e versões posteriores são compatíveis 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 desativar o Jack para usar a compatibilidade com o Java 8 incorporada ao 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 3.0.0 (ou posterior). 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 essa 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 Jack, Retrolambda ou DexGuard, 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 da 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 do método Todas
Anotações de tipo Todas. No entanto, as informações de anotação de tipo estão disponíveis no momento da compilação e não em tempo de execução. Além disso, a plataforma é compatível com TYPE na API nível 24 e anteriores, mas não com ElementType.TYPE_USE ou ElementType.TYPE_PARAMETER
Métodos de interface padrão e estáticos Todos
Repetição de anotações Todas
API da linguagem Java 8 minSdkVersion compatível
java.lang.annotation.Repeatable API nível 24 ou posterior
AnnotatedElement.getAnnotationsByType(Class) API nível 24 ou posterior
java.util.stream API nível 24 ou posterior
java.lang.FunctionalInterface API nível 24 ou posterior
java.lang.reflect.Method.isDefault() API nível 24 ou posterior
java.util.function API nível 24 ou posterior

Além dos recursos e APIs da linguagem Java 8 descritos acima, o Android Studio 3.0 e versões posteriores ampliam a compatibilidade com try-with-resources para todos os níveis de API do Android.

No momento, o Desugar não é compatível com MethodHandle.invoke ou MethodHandle.invokeExact. 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 posterior. 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, o módulo poderá não usar os métodos invoke ou invokeExact, mesmo se eles estiverem incluídos em uma dependência de biblioteca. Portanto, para continuar usando essa biblioteca com minSdkVersion 25 ou anterior, ative a redução de código para remover 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. 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, Instant Run 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 seu arquivo build.gradle do projeto:

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

Remova também o plug-in do Retrolambda e o bloco retrolambda de cada arquivo build.gradle do 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á desativá-la adicionando o seguinte ao arquivo gradle.properties:

android.enableDesugar=false
    

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