Plug-in do Android para Gradle 4.0.0 (abril de 2020)

Esta versão do plug-in do Android requer o seguinte:

4.0.1 (julho de 2020)

Esta atualização secundária oferece suporte a novas configurações e recursos padrão para visibilidade do pacote no Android 11.

Nas versões anteriores do Android, era possível acessar uma lista de todos os apps instalados em um dispositivo. No Android 11 (nível 30 da API) e versões mais recentes, por padrão, os apps têm acesso somente a uma lista filtrada de pacotes instalados. Para conferir uma lista mais ampla de apps no sistema, é preciso adicionar um elemento <queries> ao manifesto do Android do seu app ou biblioteca.

O Plug-in do Android para Gradle 4.1+ já é compatível com a nova declaração <queries>. No entanto, as versões mais antigas não são compatíveis. Se você adicionar o elemento <queries> ou começar a depender de uma biblioteca ou um SDK destinado ao Android 11, poderá encontrar erros de mesclagem de manifesto ao criar seu app.

Para resolver esse problema, estamos lançando um conjunto de patches para o Plug-in do Android para Gradle (AGP, na sigla em inglês) na versão 3.3 em diante. Se você estiver usando uma versão mais antiga do AGP, faça upgrade para uma das versões abaixo:

Versão mínima Versão padrão Observações
Gradle 6.1.1 6.1.1 Para saber mais, consulte Como atualizar o Gradle.
Ferramentas de build do SDK 29.0.2 29.0.2 Instale ou configure as Ferramentas de build do SDK.

Para mais informações sobre esse novo recurso, consulte Visibilidade do pacote no Android 11.

Novos recursos

Esta versão do Plug-in do Android para Gradle inclui os novos recursos a seguir.

Suporte ao Build Analyzer do Android Studio

A janela Build Analyzer ajuda a entender e diagnosticar problemas no processo de build, como otimizações desativadas e tarefas configuradas incorretamente. Esse recurso está disponível no Android Studio 4.0 ou mais recente com o Plug-in do Android para Gradle 4.0.0 e versões mais recentes. Abra a janela Build Analyzer no Android Studio desta forma:

  1. Crie seu app selecionando Build > Make Project na barra de menus, caso ainda não tenha feito isso.
  2. Selecione View > Tool Windows > Build na barra de menus.
  3. Na janela Build, abra a janela Build Analyzer de uma das maneiras abaixo:
    • Depois que o Android Studio concluir a criação do projeto, clique na guia Build Analyzer.
    • Depois que o Android Studio concluir a criação do seu projeto, clique no link no lado direito da janela Build Output.

A janela do Build Analyzer organiza possíveis problemas de build em uma árvore à esquerda. Inspecione e clique em cada problema para investigar os detalhes no painel à direita. Quando o Android Studio analisa seu build, ele computa o conjunto de tarefas que determinou a duração do build e fornece uma visualização para ajudar você a entender o impacto de cada tarefa. Você também pode conferir detalhes sobre os avisos abrindo o nó Warnings.

Para saber mais, leia Identificar regressões de velocidade do build.

Simplificação da biblioteca do Java 8 no D8 e R8

O Plug-in do Android para Gradle agora inclui suporte ao uso de diversas APIs da linguagem Java 8 sem a necessidade de um nível mínimo de API para seu app.

A partir do Android Studio 3.0, o compilador DEX (D8) passou a usar um processo chamado simplificação para oferecer suporte significativo a recursos da linguagem Java 8, como expressões lambda, métodos de interface padrão e try-with-resources, entre outros. No Android Studio 4.0, o mecanismo de simplificação foi estendido para poder simplificar APIs de linguagem Java. Isso significa que agora você pode incluir APIs de linguagem padrão que estavam disponíveis apenas em versões recentes do Android (como java.util.streams) em apps que oferecem suporte para versões mais antigas.

O seguinte conjunto de APIs tem suporte nessa versão:

  • Fluxos sequenciais (java.util.stream)
  • Um subconjunto de java.time
  • java.util.function
  • Adições recentes a java.util.{Map,Collection,Comparator}
  • Recursos opcionais (java.util.Optional, java.util.OptionalInt e java.util.OptionalDouble) e outras novas classes que são úteis com as APIs acima
  • Algumas adições a java.util.concurrent.atomic (novos métodos em AtomicInteger, AtomicLong e AtomicReference)
  • ConcurrentHashMap (com correções de bugs para o Android 5.0)

Para oferecer suporte a essas APIs de linguagem, o D8 compila um arquivo DEX de biblioteca separado que contém uma implementação das APIs ausentes e as inclui no seu app. O processo de simplificação reescreve o código do seu app para usar essa biblioteca durante a execução.

Para ativar o suporte para essas APIs de linguagem, inclua o seguinte no arquivo build.gradle do módulo do app:

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true // Sets Java compatibility to Java 8 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4' }

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled = true
  }

compileOptions { // Flag to enable support for the new language APIs isCoreLibraryDesugaringEnabled = true // Sets Java compatibility to Java 8 sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.0.4") }

Também pode ser necessário incluir o snippet de código acima em um arquivo build.gradle do módulo da biblioteca se:

  • Os testes de instrumentação do módulo da biblioteca usam essas APIs de linguagem, seja diretamente, pelo módulo da biblioteca ou pelas dependências dele. Dessa forma, as APIs que não estiverem presentes vão ser fornecidas para o APK de teste de instrumentação.

  • Você quiser executar o lint no módulo da biblioteca de forma isolada. O objetivo é ajudar o lint a reconhecer usos válidos das APIs de linguagem e evitar avisos falsos.

Novas opções para ativar ou desativar recursos de build

O Plug-in do Android para Gradle 4.0.0 introduz uma nova maneira de controlar quais recursos de build você quer ativar e desativar, como as vinculações de visualizações ou de dados. Quando novos recursos são adicionados, eles ficam desativados por padrão. Você pode usar o bloco buildFeatures para ativar apenas os recursos que quiser, e isso ajuda a otimizar a performance do build do projeto. Você pode definir as opções no arquivo build.gradle de cada módulo desta maneira:

android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}
android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}

Também pode especificar a configuração padrão para esses recursos em todos os módulos de um projeto incluindo uma ou mais das opções mostradas abaixo no arquivo gradle.properties do seu projeto. Não esqueça que também é possível usar o bloco buildFeatures no arquivo build.gradle de cada módulo para substituir essas configurações padrão do projeto.

android.defaults.buildfeatures.buildconfig=true
android.defaults.buildfeatures.aidl=true
android.defaults.buildfeatures.renderscript=true
android.defaults.buildfeatures.resvalues=true
android.defaults.buildfeatures.shaders=true

Dependências de recurso sobre recurso

Nas versões anteriores do Plug-in do Android para Gradle, todos os módulos de recursos podiam depender apenas do módulo base do app. Ao usar o Plug-in do Android para Gradle 4.0.0, você pode incluir um módulo de recurso que dependa de outro módulo de recurso. Ou seja, um recurso :video pode depender do recurso :camera, que depende do módulo base, como mostrado na figura abaixo.

Dependências de recurso sobre recurso

O módulo de recurso :video depende do recurso :camera, que depende do módulo base :app.

Isso significa que, quando o app solicita o download de um módulo de recurso, ele também faz o download de outros módulos de recursos de que depende. Depois de criar módulos de recursos para seu app, você pode declarar uma dependência de recursos no arquivo build.gradle do módulo. Por exemplo, o módulo :video declara uma dependência de :camera desta maneira:

// In the build.gradle file of the ':video' module.
dependencies {
  // All feature modules must declare a dependency
  // on the base module.
  implementation project(':app')
  // Declares that this module also depends on the 'camera'
  // feature module.
  implementation project(':camera')
  ...
}
// In the build.gradle file of the ':video' module.
dependencies {
    // All feature modules must declare a dependency
    // on the base module.
    implementation(project(":app"))
    // Declares that this module also depends on the 'camera'
    // feature module.
    implementation(project(":camera"))
    ...
}

Além disso, ative a função de dependência de recurso sobre recurso no Android Studio para oferecer suporte ao editar a configuração de execução, por exemplo. Faça isso clicando em Help > Edit Custom VM Options na barra de menus e incluindo o código abaixo:

-Drundebug.feature.on.feature=true

Metadados de dependências

Quando você cria seu app usando o Plug-in do Android para Gradle 4.0.0 ou versões mais recentes, o plug-in inclui metadados que descrevem as dependências compiladas no app. Durante o upload do app, o Play Console inspeciona esses metadados para oferecer estes benefícios:

  • Receber alertas de problemas conhecidos com os SDKs e as dependências que o app usa
  • Receber feedback útil para resolver esses problemas

Os dados são compactados, criptografados por uma chave de assinatura do Google Play e armazenados no bloco de assinatura do app de lançamento. No entanto, você pode inspecionar os metadados por conta própria nos arquivos de build intermediários locais no diretório <project>/<module>/build/outputs/sdk-dependencies/release/sdkDependency.txt.

Se você preferir não compartilhar essas informações, inclua o código abaixo ao arquivo build.gradle do módulo:

android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}
android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}

Importar bibliotecas nativas das dependências de AAR

Agora você pode importar bibliotecas C/C++ das dependências de AAR do app. Quando você segue as etapas de configuração descritas abaixo, o Gradle disponibiliza automaticamente essas bibliotecas nativas para uso com o sistema de build nativo externo, como o CMake. O Gradle apenas disponibiliza essas bibliotecas para o build. Você ainda precisa configurar os scripts de build para que elas possam ser usadas.

As bibliotecas são exportadas usando o formato de pacote Prefab (link em inglês).

Cada dependência pode expor, no máximo, um pacote Prefab, que compreende um ou mais módulos. Um módulo Prefab é uma única biblioteca, que pode ser compartilhada, estática ou apenas de cabeçalho.

Normalmente, o nome do pacote corresponde ao nome do artefato Maven, e o nome do módulo corresponde ao nome da biblioteca, mas nem sempre isso ocorre. Para saber o nome do pacote e do módulo das bibliotecas, consulte a documentação da dependência.

Configurar o sistema de build nativo externo

Confira as etapas abaixo que precisam ser seguidas para o sistema de build nativo externo que você planeja usar.

Cada uma das dependências de AAR do app que inclui código nativo expõe um arquivo Android.mk que você precisa importar para o projeto ndk-build. Esse arquivo é importado usando o comando import&endash;module, que pesquisa os caminhos especificados usando a propriedade import&endash;add&endash;path no projeto ndk-build. Por exemplo, se o app define libapp.so e usa curl, você precisa incluir o seguinte no arquivo Android.mk:

  1. Para o CMake:

    add_library(app SHARED app.cpp)

    # Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

  2. Para ndk-build:

    include $(CLEAR_VARS)
    LOCAL_MODULE := libapp
    LOCAL_SRC_FILES := app.cpp
    # Link libcurl from the curl AAR.
    LOCAL_SHARED_LIBRARIES := curl
    include $(BUILD_SHARED_LIBRARY)

    # If you don't expect that your project will be built using versions of the NDK # older than r21, you can omit this block. ifneq ($(call ndk-major-at-least,21),true) $(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH)) endif

    # Import all modules that are included in the curl AAR. $(call import-module,prefab/curl)

As dependências nativas incluídas em um AAR são expostas ao projeto do CMake pela variável CMAKE_FIND_ROOT_PATH{: .external} (link em inglês). Esse valor vai ser definido automaticamente pelo Gradle quando o CMake for invocado. Se o sistema de build modificar essa variável, você deve usar um anexo e não uma atribuição.

Cada dependência expõe um pacote config-file{: .external} ao build do CMake, que você importa com o comando find_package{: .external} (links em inglês). Esse comando procura por pacotes config-file que correspondam ao nome do pacote e da versão fornecidos e expõe os resultados que ele define para serem usados no build. Por exemplo, se o aplicativo definir libapp.so e usar curl, inclua o seguinte no arquivo CMakeLists.txt:


add_library(app SHARED app.cpp)

# Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

Agora, você pode especificar #include "curl/curl.h" em app.cpp. Quando você cria seu projeto, o sistema de build nativo externo vincula automaticamente libapp.so a libcurl.so e pacotes libcurl.so no APK ou no pacote de apps. Para mais informações, consulte a amostra de curl prefab{:.external} (em inglês).

Mudanças de comportamento

Ao usar esta versão do plug-in, você pode encontrar as seguintes mudanças no comportamento.

Atualizações da configuração de assinatura v1/v2

O comportamento das configurações de assinatura de apps no bloco signingConfig foi alterado para o seguinte:

Assinatura v1

  • Se v1SigningEnabled for explicitamente ativada, o AGP realizará a assinatura de apps v1.
  • Se v1SigningEnabled for explicitamente desativada pelo usuário, a assinatura de apps v1 não será realizada.
  • Se o usuário não tiver ativado a assinatura v1 explicitamente, ela pode ser desativada automaticamente com base em minSdk e targetSdk.

Assinatura v2

  • Se v2SigningEnabled for explicitamente ativada, o AGP realizará a assinatura de apps v2.
  • Se v2SigningEnabled for explicitamente desativada pelo usuário, a assinatura de apps v2 não será realizada.
  • Se o usuário não tiver ativado a assinatura v2 explicitamente, ela pode ser desativada automaticamente com base em targetSdk.

Essas mudanças permitem que o AGP otimize builds desativando o mecanismo de assinatura com base em se o usuário ativou explicitamente ou não essas flags. Antes dessa versão, era possível que v1Signing fosse desativada mesmo quando explicitamente ativada, o que poderia ser confuso.

Os Plug-ins do Android para Gradle feature e instantapp foram removidos

O Plug-in do Android para Gradle 3.6.0 descontinuou os plug-ins Feature (com.android.feature) e Instant App (com.android.instantapp) e os substituiu pelo plug-in Dynamic Feature (com.android.dynamic-feature) para criar e empacotar apps instantâneos usando Android App Bundles.

No Plug-in do Android para Gradle 4.0.0 e versões mais recentes, esses plug-ins descontinuados foram totalmente removidos. Para usar o Plug-in do Android para Gradle mais recente, você precisa migrar seu app instantâneo para o Android App Bundles. Ao migrar seus apps instantâneos, você pode aproveitar os benefícios dos pacotes de apps e simplificar o design modular do app (link em inglês).

Observação: para abrir projetos que usam os plug-ins removidos no Android Studio 4.0 e versões mais recentes, o projeto precisa usar o Plug-in do Android para Gradle 3.6.0 ou uma versão anterior.

O recurso separado de processamento de anotações foi removido

A possibilidade de separar o processamento de anotações em uma tarefa dedicada foi removida. Essa opção era usada para manter a compilação Java incremental quando processadores de anotações não incrementais eram usados em projetos somente Java. A opção era ativada configurando android.enableSeparateAnnotationProcessing como true no arquivo gradle.properties, o que não funciona mais.

Em vez disso, você precisa usar processadores de anotações incrementais para melhorar o desempenho de build.

O uso de includeCompileClasspath foi descontinuado

O Plug-in do Android para Gradle não confere mais nem inclui processadores de anotações declarados no caminho de classe de compilação, e a propriedade DSL annotationProcessorOptions.includeCompileClasspath não tem mais efeito. Se você incluir processadores de anotações no caminho de classe de compilação, poderá encontrar este erro:

Error: Annotation processors must be explicitly declared now.

Para resolver esse problema, é preciso incluir processadores de anotações nos arquivos build.gradle usando a configuração de dependência annotationProcessor. Para saber mais, leia Adicionar processadores de anotações.

Empacotamento automático de dependências pré-criadas usadas pelo CMake

As versões anteriores do Plug-in do Android para Gradle exigiam jniLibs para empacotar explicitamente quaisquer bibliotecas pré-criadas usadas pelo build nativo externo do CMake. Você pode ter bibliotecas no diretório src/main/jniLibs do seu módulo ou possivelmente em outro diretório configurado no arquivo build.gradle:

sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.srcDirs = ['libs']
  }
}
sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.setSrcDirs(listOf("libs"))
  }
}

Com o Plug-in do Android para Gradle 4.0, a configuração acima não é mais necessária e resulta em uma falha de build:

* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
  > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
    > More than one file was found with OS independent path 'lib/x86/libprebuilt.so'

O build nativo externo agora empacota automaticamente essas bibliotecas. Empacotar explicitamente a biblioteca com jniLibs resulta em uma cópia duplicada. Para evitar o erro de build, mova a biblioteca pré-criada para um local fora de jniLibs ou remova a configuração jniLibs do seu arquivo build.gradle.

Problemas conhecidos

Esta seção descreve problemas conhecidos que existem no Plug-in do Android para Gradle 4.0.0.

Disputa no mecanismo de worker do Gradle

Mudanças no Plug-in do Android para Gradle 4.0 podem acionar uma disputa no Gradle ao ser executado com &endash;&endash;no&endash;daemon e versões do Gradle 6.3 ou anteriores, fazendo que os builds travem após o término da criação.

Esse problema será corrigido no Gradle 6.4.