Usar recursos da linguagem Java 8

O Android Studio 3.0 ou posterior é compatível com todos os recursos de linguagem Java 7 e com um subconjunto de recursos da linguagem Java 8 que varia de acordo com a versão da plataforma. Esta página descreve os novos recursos da linguagem Java 8 que você pode usar, como configurar o seu projeto adequadamente para usá-los e possíveis problemas conhecidos.

Observação: o uso de recursos da linguagem Java 8 é opcional no desenvolvimento de aplicativos 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 o uso de alguns recursos da linguagem Java 8 e com algumas bibliotecas de terceiros que usam esses recursos. Como mostrado na figura 1, a cadeia 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 antes desativar o Jack para usar a compatibilidade com o Java 8 incorporada à cadeia 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 compatíveis da linguagem Java 8, atualize o plug-in do Android para 3.0.0 (ou posterior). Em seguida, para cada módulo que usar os recursos da linguagem Java 8 (no código-fonte ou nas dependências), adicione o seguinte ao seu arquivo build.gradle:

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
  }
}

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 proporcionada por essas ferramentas. No entanto, considere a migração para a cadeia 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 no momento, como descrito na tabela abaixo.

Recurso da linguagem Java 8 minSdkVersion compatível
Expressões lambda Qualquer. No entanto, a serialização lambda somente será compatível quando todos os valores capturados pelo lambda forem serializáveis.
Referências do método Qualquer.
Anotações de tipo Qualquer. 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 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 Qualquer.
Repetição de anotações Qualquer.
API da linguagem Java 8 minSdkVersion compatível
java.lang.annotation.Repeatable API de nível 24 ou superior.
AnnotatedElement.getAnnotationsByType(Class) API de nível 24 ou superior.
java.util.stream API de nível 24 ou superior.
java.lang.FunctionalInterface API de nível 24 ou superior.
java.lang.reflect.Method.isDefault() API de nível 24 ou superior.
java.util.function API de nível 24 ou superior.

Além dos recursos e APIs da linguagem Java 8 acima, o Android Studio 3.0 ou posterior amplia a compatibilidade com try-with-resources para todos os níveis de Android API.

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, 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 a usar 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, considere o uso de uma biblioteca alternativa que não use os métodos não compatíveis.

Migrar para a cadeia 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 proporcionada por essas ferramentas. No entanto, em comparação com a cadeia de ferramentas padrão, faltam a essas ferramentas algumas funcionalidades e suporte. Portanto, siga as instruções desta seção para migrar para a cadeia de ferramentas padrão do Android Studio.

Migrar do Jack

A cadeia de ferramentas Jack está obsoleta, de acordo com este anúncio. Se o projeto depender do Jack, você de migrar para a compatibilidade com o Java 8 incorporada à cadeia de ferramentas padrão do Android Studio. O uso da cadeia de ferramentas padrão também proporciona 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 a cadeia 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
    }
}

Migrar do Retrolambda

Em comparação com a cadeia 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 a cadeia 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 aprimorar a compatibilidade com o Java 8, registre um bug.