Ajouter des dépendances de build

Le système de compilation Gradle d'Android Studio permet d'inclure facilement des binaires externes ou d'autres modules de bibliothèque dans votre build en tant que dépendances. Les dépendances peuvent se trouver sur votre machine ou dans un dépôt distant, et toutes les dépendances transitives qu'elles déclarent sont également incluses automatiquement. Cette page explique comment utiliser des dépendances avec votre projet Android, y compris des détails sur les comportements et les configurations propres au plug-in Android pour Gradle. Pour une présentation plus approfondie des concepts liés aux dépendances Gradle, consultez le guide Gradle pour la gestion des dépendances. Gardez toutefois à l'esprit que votre projet Android doit exclusivement utiliser les configurations de dépendances définies sur cette page.

Types de dépendance

Pour ajouter une dépendance à votre projet, vous devez spécifier une configuration de dépendance telle que implementation dans le bloc dependencies du fichier build.gradle de votre module.

Par exemple, le fichier de module d'application build.gradle suivant inclut trois types de dépendances différents :

Groovy

plugins {
  id 'com.android.application'
}

android { ... }

dependencies {
    // Dependency on a local library module
    implementation project(':mylibrary')

    // Dependency on local binaries
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // Dependency on a remote binary
    implementation 'com.example.android:app-magic:12.3'
}

Kotlin

plugins {
    id("com.android.application")
}

android { ... }

dependencies {
    // Dependency on a local library module
    implementation(project(":mylibrary"))

    // Dependency on local binaries
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))

    // Dependency on a remote binary
    implementation("com.example.android:app-magic:12.3")
}

Chacune d'elles sollicite un type de dépendance de bibliothèque différent :

Dépendance locale – module de bibliothèque

Groovy

implementation project(':mylibrary')

Kotlin

implementation(project(":mylibrary"))

Ce segment déclare une dépendance à un module de bibliothèque Android nommé "mylibrary" (ce nom doit correspondre à celui de la bibliothèque défini par include: dans votre fichier settings.gradle). Lorsque vous compilez votre application, le système compile le module de bibliothèque et package le contenu compilé obtenu dans l'application.

Dépendance locale – binaire

Groovy

  implementation fileTree(dir: 'libs', include: ['*.jar'])
  

Kotlin

  implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
  

Gradle déclare les dépendances sur des fichiers JAR situés dans le répertoire module_name/libs/ de votre projet (Gradle interprète les chemins d'accès à partir du fichier build.gradle).

Vous pouvez également spécifier des fichiers individuels, comme suit :

Groovy

  implementation files('libs/foo.jar', 'libs/bar.jar')
  

Kotlin

  implementation(files("libs/foo.jar", "libs/bar.jar"))
  
Dépendance distante – binaire

Groovy

  implementation 'com.example.android:app-magic:12.3'
  

Kotlin

  implementation("com.example.android:app-magic:12.3")
  

Il s'agit en fait d'une notation abrégée pour les éléments suivants :

Groovy

  implementation group: 'com.example.android', name: 'app-magic', version: '12.3'

Kotlin

  implementation(group = "com.example.android", name = "app-magic", version = "12.3")

Ce segment déclare une dépendance sur la version 12.3 de la bibliothèque "app-magic", dans le groupe d'espaces de noms "com.example.android".

Remarque : Ce type de dépendances distantes nécessite que vous déclariez les dépôts distants appropriés, dans lesquels Gradle va rechercher la bibliothèque. Si la bibliothèque n'existe pas encore en local, Gradle l'extrait du site distant lorsque la compilation l'exige (par exemple, lorsque vous cliquez sur Synchroniser le projet avec les fichiers Gradle  ou lorsque vous exécutez un build).

Si vous puisez dans une dépendance AGP lors de la compilation, veillez à l'ajouter en tant que dépendance explicite. Comme le plug-in Android Gradle (AGP) utilise des configurations api/implementation en interne, certains artefacts peuvent être supprimés du classpath de compilation, qui est susceptible de changer.

Dépendances natives

À partir de la version 4.0 du plug-in Android Gradle, les dépendances natives peuvent également être importées avec la méthode décrite dans ce document.

Dépendre d'un fichier AAR qui expose des bibliothèques natives rend automatiquement ces bibliothèques disponibles pour le système de compilation utilisé par externalNativeBuild. Pour accéder aux bibliothèques à partir de votre code, vous devez les associer dans vos scripts de compilation natifs. Reportez-vous à la section Utiliser des dépendances natives de ce document.

Configurations de dépendances

Dans le bloc dependencies, vous pouvez utiliser différentes configurations de dépendance (comme implementation, présenté ci-dessus) pour déclarer une dépendance à une bibliothèque. Chaque configuration de dépendance fournit à Gradle des instructions différentes sur l'utilisation de cette dépendance. Le tableau suivant décrit chacune des configurations que vous pouvez utiliser pour les dépendances de votre projet Android. Le tableau compare également ces configurations à celles devenues obsolètes depuis la version 3.0.0 du plug-in Android Gradle.

Configuration Comportement
implementation Gradle ajoute la dépendance au classpath de compilation et la package dans la sortie de compilation. Toutefois, lorsque votre module configure une dépendance implementation, cela indique à Gradle que vous ne souhaitez pas transmettre la dépendance à d'autres modules au moment de la compilation. Autrement dit, la dépendance n'est disponible pour d'autres modules qu'au moment de l'exécution.

Utiliser cette configuration de dépendance à la place de api ou compile (obsolète) permet d'obtenir des améliorations importantes du temps de compilation, car elle réduit le nombre de modules que le système de compilation doit recompiler. Par exemple, si une dépendance implementation modifie son API, Gradle recompile uniquement cette dépendance et les modules qui en dépendent directement. Cette configuration est recommandée pour la plupart des modules d'application et de test.

api Gradle ajoute la dépendance au classpath et à la sortie de compilation. Lorsqu'un module inclut une dépendance api, cela indique à Gradle que le module souhaite exporter de manière transitoire cette dépendance vers d'autres modules, de sorte à la rendre disponible au moment de l'exécution et de la compilation.

Cette configuration se comporte exactement comme compile (désormais obsolète), mais vous devez l'utiliser avec précaution et uniquement avec les dépendances que vous devez exporter de manière transitoire vers les autres consommateurs en amont. En effet, si une dépendance api modifie son API externe, Gradle recompile tous les modules qui y ont accès au moment de la compilation. Par conséquent, la présence d'un grand nombre de dépendances api peut augmenter considérablement le temps de compilation. À moins que vous ne souhaitiez exposer l'API d'une dépendance à un module distinct, les modules de la bibliothèque doivent utiliser des dépendances implementation.

compileOnly Gradle ajoute la dépendance au classpath, mais pas à la sortie de compilation. Cette approche est utile lorsque vous créez un module Android et que vous avez besoin de sa dépendance lors de la compilation, mais qu'elle n'est pas indispensable lors de l'exécution.

Si vous utilisez cette configuration, le module de votre bibliothèque doit inclure une condition d'exécution pour vérifier si la dépendance est disponible, puis modifier correctement son comportement à la volée pour pouvoir fonctionner même si elle n'est pas fournie. Cela permet de réduire la taille de l'application finale en n'ajoutant pas de dépendances temporaires dont l'importance n'est pas critique. Cette configuration se comporte exactement comme provided (désormais obsolète).

Remarque : Vous ne pouvez pas utiliser la configuration compileOnly avec les dépendances AAR.

runtimeOnly Gradle ajoute la dépendance uniquement à la sortie de compilation, pour une utilisation en cours d'exécution. La dépendance n'est pas ajoutée au classpath de compilation. Cette configuration se comporte exactement comme apk (désormais obsolète).
annotationProcessor

Pour ajouter une dépendance à une bibliothèque en tant que processeur d'annotations, vous devez l'ajouter au classpath du processeur d'annotations à l'aide de la configuration annotationProcessor. Utiliser cette configuration améliore les performances de compilation en séparant le classpath de compilation et le classpath du processeur d'annotations. Si Gradle détecte des processeurs d'annotation sur le classpath de compilation, il désactive l'évitement de compilation, qui a un impact négatif sur le temps de compilation. (Notez que Gradle 5.0 et les versions ultérieures ignorent les processeurs d'annotations détectés sur le classpath de compilation.)

Le plug-in Android Gradle suppose qu'une dépendance est un processeur d'annotations si son fichier JAR contient l'élément suivant :

META-INF/services/javax.annotation.processing.Processor

Si le plug-in détecte un processeur d'annotations sur le classpath de compilation, il signale une erreur de compilation.

Remarque : Les projets Kotlin doivent utiliser kapt pour déclarer les dépendances du processeur d'annotations.

lintChecks

Utilisez cette configuration pour inclure les vérifications lint que vous souhaitez que Gradle exécute lors de la compilation de votre projet.

Remarque : Si vous utilisez le plug-in Android Gradle 3.4.0 ou une version ultérieure, cette configuration de dépendance ne package plus les vérifications lint dans vos projets de bibliothèque Android. Pour inclure des dépendances de vérification lint dans vos bibliothèques AAR, utilisez la configuration lintPublish décrite ci-dessous.

lintPublish Utilisez cette configuration dans les projets de bibliothèque Android pour inclure les vérifications lint que vous souhaitez voir Gradle compiler dans un fichier lint.jar et packager dans votre AAR. Avec cette approche, les projets qui consomment votre AAR appliquent également ces vérifications lint. Si vous utilisiez précédemment la configuration de dépendances lintChecks pour inclure les vérifications lint dans l'AAR publiée, vous devez migrer ces dépendances afin d'utiliser la configuration lintPublish à sa place.

Groovy


dependencies {
  // Executes lint checks from the ':checks' project at build time.
  lintChecks project(':checks')
  // Compiles lint checks from the ':checks-to-publish' into a
  // lint.jar file and publishes it to your Android library.
  lintPublish project(':checks-to-publish')
}

Kotlin


dependencies {
  // Executes lint checks from the ":checks" project at build time.
  lintChecks(project(":checks"))
  // Compiles lint checks from the ":checks-to-publish" into a
  // lint.jar file and publishes it to your Android library.
  lintPublish(project(":checks-to-publish"))
}
apk Gradle ajoute la dépendance uniquement à la sortie de compilation, pour une utilisation en cours d'exécution. La dépendance n'est pas ajoutée au classpath de compilation. Cette configuration est obsolète (disponible dans les versions 1.0 à 4.2 d'AGP).
compile Gradle ajoute la dépendance au classpath et à la sortie de compilation, puis l'exporte vers d'autres modules. Cette configuration est obsolète (disponible dans les versions 1.0 à 4.2 d'AGP).
provided Gradle ajoute la dépendance au classpath, mais pas à la sortie de compilation. Cette configuration est obsolète (disponible dans les versions 1.0 à 4.2 d'AGP).

Toutes les configurations ci-dessus appliquent les dépendances à toutes les variantes de compilation. Si vous préférez déclarer une dépendance uniquement pour l'ensemble de sources d'une variante de compilation spécifique ou pour un ensemble de sources de test, vous devez mettre en majuscules le nom de la configuration et le faire précéder du nom de l'ensemble de sources de la variante de compilation ou de test.

Par exemple, pour ajouter une dépendance implementation uniquement à votre type de produit "gratuit" (à l'aide d'une dépendance binaire distante), procédez comme suit :

Groovy

dependencies {
    freeImplementation 'com.google.firebase:firebase-ads:9.8.0'
}

Kotlin

dependencies {
    freeImplementation("com.google.firebase:firebase-ads:9.8.0")
}

Toutefois, si vous souhaitez ajouter une dépendance pour une variante qui associe un type de produit et un type de compilation, vous devez initialiser le nom de la configuration dans le bloc configurations. L'exemple suivant ajoute une dépendance runtimeOnly à votre variante de compilation "freeDebug" (en utilisant une dépendance binaire en local).

Groovy

configurations {
    // Initializes a placeholder for the freeDebugRuntimeOnly dependency configuration.
    freeDebugRuntimeOnly {}
}

dependencies {
    freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
}

Kotlin

// Initializes a placeholder for the freeDebugRuntimeOnly dependency configuration.
val freeDebugRuntimeOnly by configurations.creating

dependencies {
    freeDebugRuntimeOnly(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Pour ajouter des dépendances implementation à vos tests locaux et instrumentés, procédez comme suit :

Groovy

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.0.2'
}

Kotlin

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("androidx.test.espresso:espresso-core:3.0.2")
}

Cependant, certaines configurations n'ont aucun sens dans ce cas de figure. Par exemple, comme les autres modules ne peuvent pas dépendre de androidTest, l'avertissement suivant s'affiche si vous utilisez la configuration androidTestApi :

WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with
'androidTestImplementation'.

Ajouter des processeurs d'annotations

Si vous ajoutez des processeurs d'annotations à votre classpath de compilation, un message d'erreur semblable au suivant s'affiche :

Error: Annotation processors must be explicitly declared now.

Pour résoudre cette erreur, ajoutez des processeurs d'annotations à votre projet en configurant votre dépendance à l'aide de annotationProcessor, comme indiqué ci-dessous :

Groovy

dependencies {
    // Adds libraries defining annotations to only the compile classpath.
    compileOnly 'com.google.dagger:dagger:version-number'
    // Adds the annotation processor dependency to the annotation processor classpath.
    annotationProcessor 'com.google.dagger:dagger-compiler:version-number'
}

Kotlin

dependencies {
    // Adds libraries defining annotations to only the compile classpath.
    compileOnly("com.google.dagger:dagger:version-number")
    // Adds the annotation processor dependency to the annotation processor classpath.
    annotationProcessor("com.google.dagger:dagger-compiler:version-number")
}

Remarque : Le plug-in Android pour Gradle 3.0.0 et ses versions ultérieures ne sont plus compatibles avec le plug-in android-apt.

Transmettre des arguments aux processeurs d'annotations

Si vous devez transmettre des arguments à un processeur d'annotations, utilisez le bloc AnnotationProcessorOptions dans la configuration de compilation de votre module. Par exemple, si vous souhaitez transmettre des types de données primitifs en tant que paires clé-valeur, vous pouvez utiliser la propriété argument, comme indiqué ci-dessous :

Groovy

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                argument 'key1', 'value1'
                argument 'key2', 'value2'
            }
        }
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments += mapOf("key1" to "value1",
                                   "key2" to "value2")
            }
        }
    }
}

Toutefois, lorsque vous utilisez le plug-in Android Gradle 3.2.0 ou une version ultérieure, vous devez transmettre les arguments de processeur qui représentent des fichiers ou des répertoires directement à l'aide de l'interface CommandLineArgumentProvider de Gradle.

Utiliser CommandLineArgumentProvider permet (à vous ou à l'auteur du processeur d'annotations) d'améliorer l'exactitude et les performances des compilations propres incrémentielles et mises en cache, en appliquant des annotations de type de propriété de compilation incrémentielle à chaque argument.

Par exemple, la classe ci-dessous implémente CommandLineArgumentProvider et annote chaque argument pour le processeur. L'exemple utilise également la syntaxe du langage Groovy et est inclus directement dans le fichier build.gradle du module.

Groovy

class MyArgsProvider implements CommandLineArgumentProvider {

    // Annotates each directory as either an input or output for the
    // annotation processor.
    @InputFiles
    // Using this annotation helps Gradle determine which part of the file path
    // should be considered during up-to-date checks.
    @PathSensitive(PathSensitivity.RELATIVE)
    FileCollection inputDir

    @OutputDirectory
    File outputDir

    // The class constructor sets the paths for the input and output directories.
    MyArgsProvider(FileCollection input, File output) {
        inputDir = input
        outputDir = output
    }

    // Specifies each directory as a command line argument for the processor.
    // The Android plugin uses this method to pass the arguments to the
    // annotation processor.
    @Override
    Iterable<String> asArguments() {
        // Use the form '-Akey[=value]' to pass your options to the Java compiler.
        ["-AinputDir=${inputDir.singleFile.absolutePath}",
         "-AoutputDir=${outputDir.absolutePath}"]
    }
}

android {...}

Kotlin

class MyArgsProvider(
    // Annotates each directory as either an input or output for the
    // annotation processor.
    @get:InputFiles
    // Using this annotation helps Gradle determine which part of the file path
    // should be considered during up-to-date checks.
    @get:PathSensitive(PathSensitivity.RELATIVE)
    val inputDir: FileCollection,

    @get:OutputDirectory
    val outputDir: File
) : CommandLineArgumentProvider {
    // Specifies each directory as a command line argument for the processor.
    // The Android plugin uses this method to pass the arguments to the
    // annotation processor.

    override fun asArguments(): Iterable<String> {
        // Use the form '-Akey[=value]' to pass your options to the Java compiler.
        return listOf("-AinputDir=${inputDir.singleFile.absolutePath}",
                      "-AoutputDir=${outputDir.absolutePath}")
    }
}

android {...}

Après avoir défini une classe mettant en œuvre CommandLineArgumentProvider, vous devez créer une instance et la transmettre au plug-in Android à l'aide de la méthode annotationProcessorOptions.compilerArgumentProvider, comme indiqué ci-dessous.

Groovy

// This is in your module's build.gradle file.
android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                // Creates a new MyArgsProvider object, specifies the input and
                // output paths for the constructor, and passes the object
                // to the Android plugin.
                compilerArgumentProvider new MyArgsProvider(files("input/path"),
                                         new File("output/path"))
            }
        }
    }
}

Kotlin

// This is in your module's build.gradle file.
android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                // Creates a new MyArgsProvider object, specifies the input and
                // output paths for the constructor, and passes the object
                // to the Android plugin.
                compilerArgumentProvider(MyArgsProvider(files("input/path"),
                                                          file("output/path")))
            }
        }
    }
}

Pour savoir en quoi la mise en œuvre de CommandLineArgumentProvider permet d'améliorer les performances de compilation, consultez la page Mettre en cache des projets Java.

Désactiver la vérification des erreurs du processeur d'annotations

Si vous avez des dépendances sur le classpath de compilation qui incluent des processeurs d'annotations dont vous n'avez pas besoin, vous pouvez désactiver la vérification des erreurs en ajoutant ce qui suit à votre fichier build.gradle. N'oubliez pas que les processeurs d'annotations que vous ajoutez au classpath de compilation ne sont toujours pas ajoutés au classpath du processeur.

Groovy

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath false
            }
        }
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                argument("includeCompileClasspath", "false")
            }
        }
    }
}

Si vous utilisez du Kotlin avec kapt :

Groovy

android {
    ...
    defaultConfig {
        ...
        kapt {
            includeCompileClasspath false
        }
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        kapt {
            includeCompileClasspath = false
        }
    }
}

Si vous rencontrez des problèmes après avoir migré les processeurs d'annotations de votre projet vers le classpath du processeur, vous pouvez autoriser les processeurs d'annotations sur le classpath de compilation en définissant includeCompileClasspath sur true. Toutefois, définir cette propriété sur true n'est pas recommandé, et cette option sera supprimée lors d'une prochaine mise à jour du plug-in Android.

Exclure les dépendances transitives

À mesure qu'une application prend de l'ampleur, elle peut accumuler un certain nombre de dépendances, y compris directes ou transitives (des bibliothèques dont dépendent les bibliothèques importées par votre application). Pour exclure les dépendances transitives dont vous n'avez plus besoin, vous pouvez utiliser le mot clé exclude, comme indiqué ci-dessous :

Groovy

dependencies {
    implementation('some-library') {
        exclude group: 'com.example.imgtools', module: 'native'
    }
}

Kotlin

dependencies {
    implementation("some-library") {
        exclude(group = "com.example.imgtools", module = "native")
    }
}

Exclure les dépendances transitives des configurations de test

Si vous devez exclure certaines dépendances transitives de vos tests, l'exemple de code présenté ci-dessus risque de ne pas fonctionner comme prévu. En effet, une configuration de test (par exemple, androidTestImplementation) étend la configuration implementation du module. Autrement dit, elle contient toujours des dépendances implementation lorsque Gradle résout la configuration.

Pour exclure les dépendances transitives de vos tests, vous devez procéder au moment de l'exécution, comme indiqué ci-dessous :

Groovy

android.testVariants.all { variant ->
    variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
}

Kotlin

android.testVariants.all {
    compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
    runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
}

Remarque : Vous pouvez toujours utiliser le mot clé exclude dans le bloc de dépendances, comme indiqué dans l'exemple de code d'origine de la section Exclure les dépendances transitives, pour omettre les dépendances transitives qui sont spécifiques à la configuration de test et ne sont pas incluses dans d'autres configurations.

Configurer les dépendances d'une application Wear OS

La configuration des dépendances d'un module Wear OS est semblable à celle de tout autre module. En d'autres termes, les modules Wear OS utilisent les mêmes configurations de dépendance, telles que implementation et compileOnly.

Ces modules sont également compatibles avec la gestion des dépendances basées sur les variantes. Par conséquent, si le module de base de votre application dépend d'un module Wear, chaque variante du module de base utilise la variante correspondante de ce module Wear. Si vous créez une application simple avec une seule dépendance à un module Wear, et que celui-ci configure les mêmes variantes que votre module de base, vous devez spécifier la configuration wearApp dans le fichier build.gradle de votre module de base, comme indiqué ci-dessous :

Groovy


dependencies {
    // If the main and Wear app modules have the same variants,
    // variant-aware dependency management automatically matches
    // variants of the main app module with that of the Wear module.
    wearApp project(':wearable')
}

Kotlin


dependencies {
    // If the main and Wear app modules have the same variants,
    // variant-aware dependency management automatically matches
    // variants of the main app module with that of the Wear module.
    wearApp(project(":wearable"))
}

Si vous utilisez plusieurs modules Wear, et que vous souhaitez spécifier un module Wear différent par type d'application, vous pouvez le faire à l'aide de la configuration flavorWearApp, comme indiqué ci-dessous. Vous ne pouvez toutefois pas inclure d'autres dépendances qui utilisent la configuration wearApp.

Groovy


dependencies {
    paidWearApp project(':wear1')
    demoWearApp project(':wear1')
    freeWearApp project(':wear2')
}

Kotlin


dependencies {
    "paidWearApp"(project(":wear1"))
    "demoWearApp"(project(":wear1"))
    "freeWearApp"(project(":wear2"))
}

Dépôts distants

Lorsque votre dépendance ne concerne ni une bibliothèque ni une arborescence de fichiers locales, Gradle recherche les fichiers dans les dépôts en ligne spécifiés dans le bloc dependencyResolutionManagement { repositories {...} } de votre fichier settings.gradle. L'ordre dans lequel vous répertoriez chaque dépôt détermine l'ordre dans lequel Gradle les recherche pour chaque dépendance de projet. Par exemple, si une dépendance est disponible à partir des dépôts A et B, et que vous répertoriez d'abord A, Gradle télécharge la dépendance à partir du dépôt A.

Par défaut, les nouveaux projets Android Studio spécifient le dépôt Maven de Google et le dépôt Maven Central en tant qu'emplacements dans le fichier settings.gradle du projet, comme indiqué ci-dessous :

Groovy


dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

Kotlin


dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

Si vous souhaitez exploiter un dépôt local, utilisez mavenLocal() :

Groovy


dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        mavenLocal()
    }
}

Kotlin


dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        mavenLocal()
    }
}

Vous pouvez également déclarer des dépôts Maven ou Ivy spécifiques en procédant comme suit :

Groovy


dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        maven {
            url 'https://repo.example.com/maven2'
        }
        maven {
            url 'file://local/repo/'
        }
        ivy {
            url 'https://repo.example.com/ivy'
        }
    }
}

Kotlin


dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        maven(url = "https://repo.example.com/maven2")
        maven(url = "file://local/repo/")
        ivy(url = "https://repo.example.com/ivy")
    }
}

Pour en savoir plus, consultez le guide des dépôts Gradle.

Dépôt Maven de Google

Les versions les plus récentes des bibliothèques Android suivantes sont disponibles dans le dépôt Maven de Google :

Vous pouvez consulter tous les artefacts disponibles dans l'index du dépôt Maven de Google (voir ci-dessous pour l'accès programmatique).

Pour ajouter l'une de ces bibliothèques à votre build, incluez le dépôt Maven de Google dans votre fichier build.gradle de premier niveau :

Groovy


dependencyResolutionManagement {

    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()

        // If you're using a version of Gradle lower than 4.1, you must instead use:
        // maven {
        //     url 'https://maven.google.com'
        // }
        // An alternative URL is 'https://dl.google.com/dl/android/maven2/'.
    }
}

Kotlin


dependencyResolutionManagement {

    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()

        // If you're using a version of Gradle lower than 4.1, you must instead use:
        // maven {
        //     url = "https://maven.google.com"
        // }
        // An alternative URL is "https://dl.google.com/dl/android/maven2/".
    }
}

Ajoutez ensuite la bibliothèque souhaitée au bloc dependencies de votre module. L'exemple ci-dessous cible la bibliothèque Appcompat :

Groovy


dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
}

Kotlin


dependencies {
    implementation("com.android.support:appcompat-v7:28.0.0")
}

Toutefois, si vous essayez d'utiliser une ancienne version des bibliothèques ci-dessus et que votre dépendance échoue, cela signifie que la bibliothèque visée n'est pas disponible dans le dépôt Maven et que vous devez l'obtenir depuis le dépôt hors connexion.

Accès programmatique

Pour programmer l'accès aux artefacts Maven de Google, vous pouvez obtenir la liste XML des groupes d'artefacts à l'adresse maven.google.com/master-index.xml. Vous pouvez consulter le nom et la version des bibliothèques pour chaque groupe via :

maven.google.com/group_path/group-index.xml

Par exemple, les bibliothèques du groupe android.arch.lifecycle sont répertoriées dans maven.google.com/android/arch/lifecycle/group-index.xml.

Vous pouvez également télécharger les fichiers POM et JAR à l'adresse suivante :

maven.google.com/group_path/library/version /library-version.ext

Exemple : maven.google.com/android/arch/lifecycle/compiler/1.0.0/compiler-1.0.0.pom.

Dépôt hors connexion depuis SDK Manager

Pour les bibliothèques qui ne sont pas disponibles dans le dépôt Maven de Google (il s'agira généralement de versions plus anciennes), vous devez télécharger le package hors connexion Google Repository à partir de SDK Manager.

Vous pouvez ensuite ajouter normalement ces bibliothèques à votre bloc dependencies.

Les bibliothèques hors connexion sont enregistrées dans android_sdk/extras/.

Dépendances natives avec le plug-in Android Gradle

Les bibliothèques AAR peuvent contenir des dépendances natives que le plug-in Android Gradle peut consommer. AGP est également capable de produire des AAR qui exposent des bibliothèques natives à leurs consommateurs.

Utiliser des dépendances natives

À partir de la version 4.0 du plug-in Android Gradle, les dépendances en C/C++ peuvent être importées à partir des fichiers AAR associés dans votre fichier build.gradle. Gradle les met automatiquement à la disposition du système de compilation native, mais votre système de compilation doit être configuré pour utiliser les bibliothèques et les en-têtes importés. Étant donné que les dépendances en C/C++ sont distribuées sous forme d'AAR, les ressources suivantes concernant les AAR génériques peuvent être utiles :

  • Créer une bibliothèque Android : documentation sur les AAR génériques et comment les intégrer à votre projet, en particulier lorsque vous souhaitez utiliser un AAR comme dépendance C/C++ locale.
  • Ajouter des dépendances de compilation : pour en savoir plus sur l'ajout de dépendances à votre fichier build.gradle, en particulier pour les dépendances distantes.

Ce document explique comment configurer votre système de compilation native et suppose que vous avez déjà ajouté une AAR avec une dépendance en C/C++ dans l'environnement de compilation Gradle de votre projet.

Dépendances natives dans des AAR

Les dépendances AAR de vos modules Gradle peuvent exposer les bibliothèques natives qui seront utilisées par votre application. Dans l'AAR, le répertoire prefab contient un package Prefab, qui inclut les en-têtes et les bibliothèques de la dépendance native.

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 uniquement.

Les noms des packages et des modules doivent être connus pour pouvoir utiliser les bibliothèques. Par convention, le nom du package correspond au nom de l'artefact Maven et le nom du module au nom de la bibliothèque C/C++. Ce n'est cependant pas une obligation. Consultez la documentation de la dépendance pour déterminer les noms qu'elle utilise.

Créer une configuration système

La fonctionnalité prefab doit être activée pour votre module Android Gradle.

Pour ce faire, ajoutez le code suivant au bloc android du fichier build.gradle de votre module :

Groovy

buildFeatures {
  prefab true
}

Kotlin

buildFeatures {
  prefab = true
}

Vous pouvez éventuellement configurer une version dans le fichier gradle.properties de votre projet :

android.prefabVersion=2.0.0

En général, la version AGP sélectionnée par défaut répond à vos besoins. Vous ne devez sélectionner une version différente que si vous avez besoin de contourner un bug ou d'exploiter une nouvelle fonctionnalité.

Les dépendances importées à partir d'un AAR sont exposées à CMake via CMAKE_FIND_ROOT_PATH. Cette valeur est définie automatiquement par Gradle lorsque CMake est appelé. Par conséquent, si votre compilation modifie cette variable, assurez-vous de l'ajouter au lieu de l'attribuer.

Chaque dépendance expose un package config-file à votre build. Les packages sont importés via la commande find_package. 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 pour permettre leur utilisation dans votre build. Par exemple, si votre application définit libapp.so et qu'elle utilise cURL, votre fichier CMakeLists.txt doit inclure les éléments suivants :

add_library(app SHARED app.cpp)

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

app.cpp permet désormais de #include "curl/curl.h", et libapp.so sera automatiquement associé à libcurl.so lors de la compilation, tandis que libcurl.so sera inclus avec l'application.

Publier des bibliothèques natives dans des AAR

La possibilité de créer des AAR natives a été ajoutée pour la première fois dans la version 4.1 d'AGP.

Pour exporter vos bibliothèques natives, ajoutez le code suivant au bloc android du fichier build.gradle de votre projet de bibliothèque :

Groovy


buildFeatures {
    prefabPublishing true
}

prefab {
    mylibrary {
      headers "src/main/cpp/mylibrary/include"
    }

    myotherlibrary {
        headers "src/main/cpp/myotherlibrary/include"
    }
}

Kotlin


buildFeatures {
    prefabPublishing = true
}

prefab {
    create("mylibrary") {
      headers = "src/main/cpp/mylibrary/include"
    }

    create("myotherlibrary") {
        headers = "src/main/cpp/myotherlibrary/include"
    }
}

Dans cet exemple, les bibliothèques mylibrary et myotherlibrary de votre compilation externe ndk-build ou CMake native seront packagées dans l'AAR produit par votre compilation, et chacune exportera les en-têtes de dans le répertoire spécifié pour les éléments qui en dépendent.

Ordre des dépendances

La liste de vos dépendances définit leur ordre de priorité : la première bibliothèque répertoriée est prioritaire sur la deuxième, qui est prioritaire sur la troisième, etc. Cet ordre est important si des ressources sont fusionnées ou si des éléments du fichier manifeste sont fusionnés dans votre application à partir des bibliothèques.

Par exemple, si votre projet déclare :

  • une dépendance à LIB_A et LIB_B (dans cet ordre) ;
  • LIB_A dépend de LIB_C et LIB_D (dans cet ordre) ; et
  • LIB_B dépend également de LIB_C.

L'ordre de priorité des dépendances sera le suivant :

  1. LIB_A
  2. LIB_D
  3. LIB_B
  4. LIB_C

Ainsi LIB_A et LIB_B peuvent ignorer LIB_C, et LIB_D a une priorité plus élevée que LIB_B, car LIB_A (qui en dépend) a une priorité plus élevée que LIB_B.

Pour en savoir plus sur la fusion des fichiers manifestes de différentes sources/dépendances de projet, consultez la section Fusionner plusieurs fichiers manifestes.

Afficher les dépendances du module

Certaines dépendances directes peuvent avoir leurs propres dépendances. Celles-ci sont des dépendances transitives. Plutôt que de vous demander de déclarer manuellement chaque dépendance transitive, Gradle les collecte et les ajoute automatiquement pour vous. Le plug-in Android pour Gradle fournit une tâche qui affiche une liste des dépendances résolues par Gradle pour un module donné.

Pour chaque module, le rapport regroupe également les dépendances en fonction de la variante de compilation, de l'ensemble de sources de test et du classpath. Voici un exemple de rapport pour le classpath d'exécution d'un module d'application dans sa variante de compilation de débogage, et pour le classpath de compilation de son ensemble de sources de test instrumenté.

debugRuntimeClasspath - Dependencies for runtime/packaging
+--- :mylibrary (variant: debug)
+--- com.google.android.material:material:1.0.0@aar
+--- androidx.appcompat:appcompat:1.0.2@aar
+--- androidx.constraintlayout:constraintlayout:1.1.3@aar
+--- androidx.fragment:fragment:1.0.0@aar
+--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
+--- androidx.recyclerview:recyclerview:1.0.0@aar
+--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
...

debugAndroidTest
debugAndroidTestCompileClasspath - Dependencies for compilation
+--- androidx.test.ext:junit:1.1.0@aar
+--- androidx.test.espresso:espresso-core:3.1.1@aar
+--- androidx.test:runner:1.1.1@aar
+--- junit:junit:4.12@jar
...

Pour exécuter la tâche, procédez comme suit :

  1. Sélectionnez Afficher > Fenêtres d'outils > Gradle ou cliquez sur Gradle  dans la barre des fenêtres d'outils.
  2. Développez AppName > Tâches > Android, puis double-cliquez sur androidDependencies. Une fois que Gradle a exécuté la tâche, la fenêtre Exécuter doit afficher le résultat.

Pour en savoir plus sur la gestion des dépendances dans Gradle, consultez la section Principes de base pour la gestion des dépendances dans le guide de l'utilisateur de Gradle.

Corriger les erreurs de résolution des dépendances

Lorsque vous ajoutez plusieurs dépendances à votre projet d'application, ces dépendances directes et transitives peuvent entrer en conflit. Le plug-in Android Gradle tente de résoudre ces conflits sans complications, mais certains cas peuvent entraîner des erreurs de compilation ou d'exécution.

Pour vous aider à identifier l'origine des erreurs, inspectez l'arborescence des dépendances de votre application et recherchez celles qui apparaissent plusieurs fois ou dont les versions posent problème.

Si vous ne parvenez pas à identifier facilement les dépendances en double, utilisez l'interface d'Android Studio pour rechercher les dépendances qui incluent la classe en double. Procédez comme suit :

  1. Sélectionnez Naviguer > Classe dans la barre de menu.
  2. Dans la boîte de dialogue de recherche pop-up, assurez-vous que la case Inclure les éléments extérieurs au projet est cochée.
  3. Saisissez le nom de la classe qui apparaît dans l'erreur de compilation.
  4. Inspectez les résultats pour les dépendances qui incluent la classe.

Les sections suivantes décrivent les différents types d'erreurs de résolution de dépendances que vous pouvez rencontrer, et comment les résoudre.

Corriger les erreurs de classe en double

Si une classe apparaît plusieurs fois dans le classpath d'exécution, cela produit une erreur semblable à celle-ci :

Program type already present com.example.MyClass

Cette erreur survient généralement dans l'un des cas suivants :

  • Une dépendance binaire inclut une bibliothèque que votre application inclut également en tant que dépendance directe. Par exemple, votre application déclare une dépendance directe aux bibliothèques A et B, mais la bibliothèque A inclut déjà la bibliothèque B dans son binaire.
    • Pour résoudre ce problème, supprimez la bibliothèque B des dépendances directes.
  • Votre application dispose d'une dépendance binaire locale et d'une dépendance binaire distante à la même bibliothèque.
    • Pour résoudre ce problème, supprimez l'une des dépendances binaires.

Résoudre les conflits de classpath

Au moment de résoudre le classpath de compilation, Gradle commence par résoudre le classpath d'exécution et utilise le résultat pour déterminer les versions des dépendances qui doivent être ajoutées au classpath de compilation. En d'autres termes, classpath d'exécution détermine les numéros de version requis pour les dépendances identiques des classpaths en aval.

Le classpath d'exécution de votre application détermine également les numéros de version requis par Gradle pour mettre en correspondance les dépendances dans le classpath d'exécution de l'APK de test de l'application. La hiérarchie des classpaths est décrite à la figure 1.

Figure 1 : Les numéros de version des dépendances qui apparaissent dans plusieurs classpaths doivent correspondre en fonction de la hiérarchie ci-dessus.

Un conflit peut survenir lorsque différentes versions de la même dépendance apparaissent sur plusieurs classpath (par exemple, lorsque votre application inclut une version d'une dépendance sous la configuration de dépendance implementation alors qu'un module de bibliothèque exploite une autre version de cette dépendance sous la configuration runtimeOnly).

Lors de la résolution des dépendances dans les classpaths d'exécution et de compilation, le plug-in Android Gradle 3.3.0 et ses versions ultérieures tentent de résoudre automatiquement certains des conflits de version en aval. Par exemple, si le classpath d'exécution inclut la bibliothèque A en version 2.0 tandis que le classpath de compilation inclut la bibliothèque A en version 1.0, le plug-in met automatiquement à jour la dépendance dans le classpath de compilation vers la version 2.0 de la bibliothèque A, pour éviter les erreurs.

Par contre, si le classpath d'exécution inclut la bibliothèque A en version 1.0 et que le classpath de compilation inclut la bibliothèque A en version 2.0, le plug-in ne rétrograde pas la version de la dépendance dans le classpath de compilation. Ce cas de figure produit une erreur semblable à la suivante :

Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'.
Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.

Pour résoudre ce problème, effectuez l'une des opérations suivantes :

  • Incluez la version souhaitée de la dépendance en tant que dépendance api dans votre module de bibliothèque. Autrement dit, seul votre module de bibliothèque déclare la dépendance, mais le module de l'application aura également accès à son API de manière transitoire.
  • Vous pouvez également déclarer la dépendance dans les deux modules, mais vous devrez alors vous assurer qu'ils utilisent la même version. Envisagez de configurer des propriétés à l'échelle du projet pour vous assurer que les versions de chaque dépendance restent cohérentes dans votre projet.

Appliquer une logique de compilation personnalisée

Cette section décrit des sujets avancés qui peuvent vous être utiles lorsque vous souhaitez étendre le plug-in Android Gradle ou écrire votre propre plug-in.

Publier des dépendances de variantes dans une logique personnalisée

Une bibliothèque peut comporter des fonctionnalités que d'autres projets ou sous-projets pourraient utiliser. La publication d'une bibliothèque est le processus par lequel elle est mise à la disposition de ses consommateurs. Les bibliothèques peuvent contrôler les dépendances auxquelles leurs utilisateurs ont accès au moment de la compilation et de l'exécution.

Deux configurations distinctes contiennent les dépendances transitives de chaque classpath que les consommateurs doivent utiliser pour exploiter la bibliothèque, comme décrit ci-dessous :

  • variant_nameApiElements : cette configuration contient les dépendances transitives disponibles pour les consommateurs lors de la compilation.
  • variant_nameRuntimeElements : cette configuration contient les dépendances transitives disponibles pour les consommateurs lors de l'exécution.

Pour en savoir plus sur les relations entre les différentes configurations, consultez la section Configurations du plug-in Java Library.

Stratégies personnalisées pour la résolution des dépendances

Un projet peut inclure une dépendance sur deux versions différentes de la même bibliothèque, ce qui peut entraîner des conflits de dépendances. Par exemple, si votre projet dépend de la version 1 du module A et de la version 2 du module B, et que le module A dépend de manière transitoire de la version 3 du module B, il existe un conflit de version de dépendance.

Pour résoudre ce conflit, le plug-in Android Gradle utilise la stratégie de résolution des dépendances suivante : lorsque différentes versions du même module figurent dans le graphique de dépendance, la version dont le numéro est le plus élevé est choisie par défaut.

Cependant, cette stratégie peut ne pas produire les résultats escomptés. Pour personnaliser la stratégie de résolution des dépendances, utilisez les configurations suivantes afin de résoudre les dépendances spécifiques à une variante et nécessaires à votre tâche :

  • variant_nameCompileClasspath : cette configuration contient la stratégie de résolution pour le classpath de compilation d'une variante donnée.
  • variant_nameRuntimeClasspath : cette configuration contient la stratégie de résolution pour le classpath d'exécution d'une variante donnée.

Le plug-in Android Gradle inclut des getters que vous pouvez utiliser pour accéder aux objets de configuration de chaque variante. Ainsi, vous pouvez utiliser l'API des variantes pour interroger la résolution des dépendances, comme indiqué dans l'exemple ci-dessous :

Groovy

android {
    applicationVariants.all { variant ->
        // Return compile configuration objects of a variant.
        variant.getCompileConfiguration().resolutionStrategy {
        // Use Gradle's ResolutionStrategy API
        // to customize how this variant resolves dependencies.
            ...
        }
        // Return runtime configuration objects of a variant.
        variant.getRuntimeConfiguration().resolutionStrategy {
            ...
        }
        // Return annotation processor configuration of a variant.
        variant.getAnnotationProcessorConfiguration().resolutionStrategy {
            ...
        }
    }
}

Kotlin

android {
    applicationVariants.all {
        // Return compile configuration objects of a variant.
        compileConfiguration.resolutionStrategy {
        // Use Gradle's ResolutionStrategy API
        // to customize how this variant resolves dependencies.
            ...
        }
        // Return runtime configuration objects of a variant.
        runtimeConfiguration.resolutionStrategy {
            ...
        }
        // Return annotation processor configuration of a variant.
        annotationProcessorConfiguration.resolutionStrategy {
            ...
        }
    }
}

Informations sur les dépendances pour la Play Console

Lorsque vous compilez votre application à l'aide d'AGP 4.0.0 ou d'une version ultérieure, le plug-in inclut des métadonnées décrivant les dépendances de bibliothèque compilées dans votre application. Lors de l'importation de votre application, la Play Console inspecte ces métadonnées pour générer des alertes sur les problèmes connus liés aux SDK et aux dépendances utilisés par votre application (et dans certains cas, fournir 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 release. Nous recommandons de conserver ce fichier pour offrir une expérience utilisateur positive et sécurisée. Toutefois, si vous préférez ne pas partager ces informations, vous pouvez inclure le bloc dependenciesInfo suivant 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
    }
}

Pour en savoir plus sur nos règles et les problèmes potentiels liés aux dépendances, consultez notre page d'assistance sur l'utilisation de SDK tiers dans votre application.