Plug-in Android Gradle 4.0.0 (avril 2020)

Cette version du plug-in d'Android nécessite les éléments suivants :

Version 4.0.1 (juillet 2020)

Cette mise à jour mineure est compatible avec les nouveaux paramètres et fonctionnalités par défaut pour la visibilité des packages sous Android 11.

Dans les versions précédentes d'Android, vous pouviez afficher la liste de toutes les applications installées sur un appareil. À partir d'Android 11 (niveau d'API 30), les applications par défaut n'ont plus accès qu'à une liste filtrée des packages installés. Pour afficher une liste plus complète d'applications sur le système, vous devez désormais ajouter un élément <queries> dans le fichier manifeste Android de votre application ou de votre bibliothèque.

Le plug-in 4.1 ou version ultérieure d'Android Gradle est déjà compatible avec la nouvelle déclaration <queries>. Toutefois, les anciennes versions ne sont pas compatibles. Si vous ajoutez l'élément <queries> ou si vous utilisez une bibliothèque ou un SDK compatibles avec le ciblage sous Android 11, vous pouvez rencontrer des erreurs liées à la fusion de fichiers manifestes au moment de créer votre application.

Pour résoudre ce problème, nous proposons un ensemble de correctifs pour l'AGP 3.3 ou version ultérieure. Si vous utilisez une ancienne version de l'AGP, passez à l'une des versions suivantes :

Si vous utilisez la version de l'
AGP
Passez à la version:
4.0.* 4.0.1
3.6.* 3.6.4
3,5.* 3.5.4
3.4.* 3.4.3
3.3.* 3.3.3

Pour en savoir plus sur cette nouvelle fonctionnalité, consultez Visibilité des packages sous Android 11.

Nouvelles fonctionnalités

Cette version du plug-in d'Android Gradle inclut les nouvelles fonctionnalités suivantes.

Compatibilité avec Build Analyzer d'Android Studio

La fenêtre Build Analyzer vous permet de comprendre et de diagnostiquer les problèmes liés à votre processus de compilation, tels que les optimisations désactivées et les tâches mal configurées. Cette fonctionnalité est disponible lorsque vous utilisez Android Studio 4.0 ou version ultérieure avec le plug-in Android Gradle 4.0.0 ou version ultérieure. Vous pouvez ouvrir la fenêtre Build Analyzer à partir d'Android Studio comme suit :

  1. Si vous ne l'avez pas déjà fait, créez votre application en sélectionnant Build > Make Project (Compiler > Créer un projet) dans la barre de menu.
  2. Sélectionnez View > Tool Windows > Build (Affichage > Fenêtres d'outils > Compiler) dans la barre de menu.
  3. Dans la fenêtre Build (Compiler), ouvrez la fenêtre Build Analyzer de l'une des manières suivantes :
    • Lorsqu'Android Studio a terminé la création de votre projet, cliquez sur l'onglet Build Analyzer.
    • Lorsqu'Android Studio a terminé la création de votre projet, cliquez sur le lien situé à droite de la fenêtre Build Output (Sortie de compilation).

La fenêtre Build Analyzer organise les éventuels problèmes de compilation dans une arborescence à gauche. Vous pouvez examiner chaque problème et cliquer dessus pour examiner ses détails dans le panneau de droite. Quand Android Studio analyse votre build, il calcule l'ensemble des tâches qui ont déterminé la durée de la compilation et propose une vue qui vous aide à comprendre l'effet de chacune de ces tâches. Vous pouvez également obtenir des détails sur les avertissements en développant le nœud Warnings (Avertissements).

Pour en savoir plus, consultez Identifier les régressions de vitesse de compilation.

Désucrage de la bibliothèque Java 8 dans D8 et R8

Le plug-in Android Gradle est désormais compatible avec un certain nombre d'API Java 8, sans nécessiter de niveau d'API minimal pour votre application.

Grâce à un processus appelé désucrage, le compilateur DEX, D8, d'Android Studio 3.0 et versions ultérieures était déjà compatible avec les fonctionnalités du langage Java 8 (telles que les expressions lambda, les méthodes d'interface par défaut et les tentatives avec des ressources). Dans Android Studio 4.0, le moteur de désucrage a été étendu de manière à pouvoir désucrer les API de langage Java. Cela signifie que vous pouvez désormais inclure des API en langage standard qui n'étaient disponibles que dans les versions récentes d'Android (comme java.util.streams) dans les applications compatibles avec d'anciennes versions.

L'ensemble d'API suivant est compatible avec cette version :

  • Flux séquentiels (java.util.stream)
  • Un sous-ensemble de java.time
  • java.util.function
  • Ajouts récents à java.util.{Map,Collection,Comparator}
  • Options (java.util.Optional, java.util.OptionalInt et java.util.OptionalDouble) et autres nouvelles classes utiles avec les API ci-dessus
  • Ajouts à java.util.concurrent.atomic (nouvelles méthodes sur AtomicInteger, AtomicLong et AtomicReference)
  • ConcurrentHashMap (avec corrections de bugs pour Android 5.0)

Pour prendre en charge ces API de langage, D8 compile un fichier DEX de bibliothèque distinct qui contient une implémentation des API manquantes et l'inclut dans votre application. Le processus de désucrage réécrit le code de votre application pour utiliser à la place cette bibliothèque lors de l'exécution.

Pour activer la compatibilité avec ces API de langage, incluez les éléments suivants dans le fichier build.gradle de votre module d'application :

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

Notez que vous devrez peut-être également ajouter l'extrait de code ci-dessus dans le fichier build.gradle d'un module de bibliothèque dans les cas suivants :

  • Les tests instrumentés du module de bibliothèque utilisent des API reposant sur ce langage (soit directement, soit via le module de bibliothèque ou ses dépendances). Cela permet de fournir les API manquantes pour votre APK de test instrumenté.

  • Vous souhaitez exécuter lint sur le module de la bibliothèque de manière isolée. Cela permet à lint d'identifier les utilisations valides des API de langage et d'éviter de signaler de faux avertissements.

Nouvelles options pour activer ou désactiver les fonctionnalités de compilation

Le plug-in Android Gradle 4.0.0 introduit un nouveau moyen de contrôler les fonctionnalités de compilation que vous souhaitez activer et désactiver, telles que la liaison de vue et la liaison de données. Lorsque de nouvelles fonctionnalités sont ajoutées, elles sont désactivées par défaut. Vous pouvez ensuite utiliser le bloc buildFeatures pour activer uniquement les fonctionnalités de votre choix et optimiser les performances de compilation pour votre projet. Vous avez la possibilité de définir les options de chaque module dans le fichier build.gradle au niveau du module, comme suit :

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

Vous pouvez également préciser le paramètre par défaut pour ces fonctionnalités dans tous les modules d'un projet en incluant un ou plusieurs des éléments suivants dans le fichier gradle.properties de votre projet, comme indiqué ci-dessous. N'oubliez pas que vous pouvez toujours utiliser le bloc buildFeatures dans le fichier build.gradle au niveau du module pour ignorer ces paramètres par défaut à l'échelle du projet.

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

Dépendances entre fonctionnalités

Dans les versions précédentes du plug-in Android Gradle, tous les modules de fonctionnalités pouvaient dépendre uniquement du module de base de l'application. Lorsque vous utilisez le plug-in Android Gradle 4.0.0 ou version ultérieure, vous pouvez désormais inclure un module de fonctionnalité qui dépend d'un autre module de fonctionnalité. Autrement dit, une fonctionnalité :video peut dépendre de la fonctionnalité :camera, qui dépend du module de base, comme l'illustre la figure ci-dessous.

Dépendances entre fonctionnalités

Le module de fonctionnalité :video dépend de la fonctionnalité :camera, qui dépend du module :app de base.

Cela signifie que lorsque votre application demande à télécharger un module de fonctionnalité, elle télécharge également d'autres modules de fonctionnalités dont elle dépend. Après avoir créé des modules de fonctionnalités pour votre application, vous pouvez déclarer une dépendance entre fonctionnalités dans le fichier build.gradle du module. Par exemple, le module :video déclare une dépendance à :camera comme suit :

// 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"))
    ...
}

En outre, vous devez activer la fonction de dépendance entre fonctionnalités dans Android Studio (pour la prendre en charge lorsque vous modifiez la configuration d'exécution, par exemple). Pour cela, cliquez sur Help > Edit Custom VM Options (Aide > Modifier les options de VM personnalisées) dans la barre de menu et incluez ce qui suit :

-Drundebug.feature.on.feature=true

Métadonnées de dépendances

Si vous compilez votre application à l'aide du plug-in Android Gradle 4.0.0 ou version ultérieure, le plug-in inclut des métadonnées décrivant les dépendances compilées dans votre application. Lorsque vous importez votre application, la Play Console inspecte ces métadonnées pour vous proposer les avantages suivants :

  • Recevoir des alertes de problèmes connus liés aux SDK et aux dépendances utilisés par votre application
  • Recevoir des commentaires exploitables pour résoudre ces problèmes

Les données sont compressées, chiffrées par une clé de signature Google Play et stockées dans le bloc de signature de votre application de publication. Toutefois, vous pouvez inspecter vous-même les métadonnées dans les fichiers de compilation intermédiaires locaux dans le répertoire <project>/<module>/build/outputs/sdk-dependencies/release/sdkDependency.txt.

Si vous préférez ne pas partager ces informations, vous pouvez les désactiver en incluant les éléments suivants dans le fichier build.gradle de votre module :

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

Importer des bibliothèques natives à partir de dépendances AAR

Vous pouvez désormais importer des bibliothèques C/C++ à partir des dépendances AAR de votre application. Lorsque vous suivez les étapes de configuration décrites ci-dessous, Gradle rend automatiquement ces bibliothèques natives disponibles pour votre système de compilation natif externe, comme CMake. Notez que Gradle se limite à rendre ces bibliothèques disponibles pour votre compilation. Vous devez toutefois configurer vos scripts de compilation pour les utiliser.

Les bibliothèques sont exportées au format de package Prefab.

Chaque dépendance peut exposer au maximum un package Prefab, qui comprend un ou plusieurs modules. Un module Prefab est une bibliothèque unique, qui peut être une bibliothèque partagée, statique ou en-tête seulement.

En règle générale, le nom du package correspond au nom de l'artefact Maven et le nom du module au nom de la bibliothèque, mais pas toujours. Comme vous devez connaître le nom du package et du module des bibliothèques, vous devrez peut-être consulter la documentation de la dépendance pour déterminer ces noms.

Configurer votre système de compilation natif externe

Pour connaître la procédure qui s'applique, suivez les étapes ci-dessous correspondant au système de compilation natif externe que vous prévoyez d'utiliser.

Chacune des dépendances AAR de votre application qui inclut du code natif expose un fichier Android.mk que vous devez importer dans votre projet ndk-build. Importez ce fichier en exécutant la commande import&endash;module, qui recherche les chemins d'accès que vous indiquez à l'aide de la propriété import&endash;add&endash;path de votre projet ndk-build. Par exemple, si votre application définit libapp.so et qu'elle utilise curl, vous devez inclure les éléments suivants dans votre fichier Android.mk :

  1. Pour CMake :

    add_library(app SHARED app.cpp)

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

  2. Pour 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)

Les dépendances natives incluses dans un AAR sont exposées à votre projet CMake via la variable CMake_find_ROOT_PATH{: .external}. Cette valeur est définie automatiquement par Gradle lorsque CMake est appelé. Si votre système de compilation modifie cette variable, veillez à l'ajouter au lieu de l'attribuer.

Chaque dépendance expose un package config-file{: .external} à votre build CMake, que vous importez à l'aide de la commande find_package{: .external}. Cette commande recherche les packages config-file correspondant au nom et à la version de package spécifiés, et expose les cibles qu'elle définit afin qu'elles soient utilisées dans votre build. Par exemple, si votre application définit libapp.so et qu'elle utilise curl, vous devez inclure les éléments suivants dans votre fichier CMakeLists.txt :


add_library(app SHARED app.cpp)

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

Vous pouvez désormais indiquer #include "curl/curl.h" dans app.cpp. Lorsque vous compilez votre projet, votre système de compilation natif externe associe automatiquement libapp.so à libcurl.so et aux packages libcurl.so dans l'APK ou l'app bundle. Pour en savoir plus, consultez l'exemple Prefab curl{:.external}.

Changements de comportement

Si vous utilisez cette version du plug-in, vous pouvez observer les changements de comportement suivants.

Mises à jour de la configuration de signature en v1/v2

Le comportement des configurations de signature d'application dans le bloc signingConfig a été modifié comme suit :

Signature en v1

  • Si v1SigningEnabled est explicitement activé, l'AGP effectue une signature d'application en v1.
  • Si v1SigningEnabled est explicitement désactivé par l'utilisateur, la signature d'application en v1 n'est pas effectuée.
  • Si l'utilisateur n'a pas explicitement activé la signature en v1, celle-ci peut être automatiquement désactivée en fonction de minSdk et de targetSdk.

Signature en v2

  • Si v2SigningEnabled est explicitement activé, l'AGP effectue une signature d'application en v2.
  • Si v2SigningEnabled est explicitement désactivé par l'utilisateur, la signature d'application en v2 n'est pas effectuée.
  • Si l'utilisateur n'a pas explicitement activé la signature en v2, celle-ci peut être automatiquement désactivée en fonction de targetSdk.

Ces modifications permettent à l'AGP d'optimiser les compilations en désactivant le mécanisme de signature selon que l'utilisateur a explicitement activé ces indicateurs. Dans les versions précédentes, il était possible de désactiver v1Signing, même lorsqu'il était explicitement activé, ce qui pouvait être déroutant.

Suppression des plug-ins Android Gradle feature et instantapp

Le plug-in Android Gradle 3.6.0 a rendu obsolètes les plug-ins Feature (com.android.feature) et Instant App (com.android.instantapp) au lieu d'utiliser le plug-in Dynamic Feature (com.android.dynamic-feature) pour compiler et empaqueter vos applis instantanées à l'aide d'Android App Bundles.

Dans le plug-in Android Gradle 4.0.0 ou version ultérieure, ces plug-ins obsolètes sont entièrement supprimés. Ainsi, pour utiliser le dernier plug-in Android Gradle, vous devez migrer votre appli instantanée pour la rendre compatible avec le format Android App Bundle. En migrant vos applis instantanées, vous pouvez exploiter les avantages des app bundles et simplifier la conception modulaire de votre application.

Remarque : Pour ouvrir des projets qui utilisent les plug-ins supprimés dans Android Studio 4.0 ou version ultérieure, le projet doit utiliser le plug-in Android Gradle 3.6.0 ou version antérieure.

Suppression de la fonctionnalité permettant de traiter les annotations à part

La fonctionnalité permettant de traiter les annotations dans une tâche à part a été supprimée. Cette option a servi à maintenir la compilation Java incrémentale lorsque des processeurs d'annotations non incrémentiels étaient utilisés uniquement dans des projets Java. Elle a été activée en définissant android.enableSeparateAnnotationProcessing sur true dans le fichier gradle.properties, ce qui ne fonctionne plus.

À la place, vous devez migrer vers des processeurs d'annotation incrémentiels pour améliorer les performances de compilation.

includeCompileClasspath est obsolète

Le plug-in Android Gradle ne vérifie plus et n'inclut plus les processeurs d'annotations que vous déclarez sur le classpath de compilation, et la propriété DSL annotationProcessorOptions.includeCompileClasspath n'a plus aucun effet. Si vous incluez des processeurs d'annotations dans le classpath de compilation, vous pouvez obtenir l'erreur suivante :

Error: Annotation processors must be explicitly declared now.

Pour résoudre ce problème, vous devez inclure des processeurs d'annotations dans vos fichiers build.gradle à l'aide de la configuration des dépendances annotationProcessor. Pour en savoir plus, consultez Ajouter des processeurs d'annotations.

Empaquetage automatique des dépendances précompilées utilisées par CMake

Les versions antérieures du plug-in Android Gradle nécessitaient d'empaqueter explicitement toutes les bibliothèques précompilées utilisées par votre compilation native externe CMake à l'aide de jniLibs. Le répertoire src/main/jniLibs de votre module peut contenir des bibliothèques, ou éventuellement un autre répertoire configuré dans votre fichier 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"))
  }
}

Avec le plug-in Android Gradle 4.0, la configuration mentionnée précédemment n'est plus nécessaire et fait échouer la compilation :

* 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'

La compilation native externe empaquette désormais automatiquement ces bibliothèques. Avec jniLibs, cela peut donc entraîner la création d'un double. Pour éviter l'erreur de compilation, déplacez la bibliothèque précompilée vers un emplacement hors de jniLibs ou supprimez la configuration jniLibs de votre fichier build.gradle.

Problèmes connus

Cette section décrit les problèmes connus du plug-in 4.0.0 d'Android Gradle.

Condition de concurrence dans le mécanisme des nœuds de calcul de Gradle

Les modifications apportées au plug-in Android Gradle 4.0 peuvent déclencher une condition de concurrence dans Gradle lorsque vous exécutez la commande avec &endash;&endash;no&endash;daemon et Gradle 6.3 ou version antérieure, ce qui entraîne le blocage des compilations une fois celles-ci terminées.

Ce problème sera résolu dans Gradle 6.4.