Interdépendances entre les outils et les bibliothèques

Les dépendances de compilation sont des composants externes requis pour compiler correctement votre projet. Une compilation peut dépendre de bibliothèques, plug-ins, sous-projets, du SDK Android, d'outils tels que les compilateurs Kotlin et Java, les environnements de développement comme Android Studio et Gradle lui-même.

Chaque dépendance peut elle-même nécessiter d'autres dépendances. Nous les appelons dépendances transitives et peuvent augmenter rapidement les dépendances globales utilisées par votre application. Lorsque vous souhaitez mettre à niveau une dépendance, qu'il s'agisse d'une bibliothèque, d'un outil ou du SDK Android, cette mise à niveau peut se propager à de nombreuses autres dépendances.

Souvent, cela ne pose pas de problème, car de nombreuses bibliothèques suivent un schéma appelé gestion sémantique des versions. Ces bibliothèques limitent les types de modifications qu'elles apportent pour assurer la compatibilité avec leurs versions antérieures.

La gestion des versions sémantique suit un format major.minor.patch. Par exemple, dans le numéro de version 4.8.3, 4 correspond à la version major, 8 à la version minor et 3 au numéro patch. Lorsque la partie major change, la bibliothèque peut subir des modifications importantes de l'API ou du comportement. Cela peut avoir un impact sur le comportement de votre build ou de votre application.

Lorsque les parties minor (nouvelles fonctionnalités) ou patch (correction de bugs) changent, les développeurs de la bibliothèque vous indiquent que celle-ci est toujours compatible et ne devrait pas avoir d'incidence sur votre application.

Il est important de surveiller ces modifications. Plusieurs outils de mise à niveau des dépendances peuvent vous y aider.

Relations dans votre build

Les builds Android contiennent des relations entre les éléments suivants :

  • Code source : code et ressources que vous contrôlez
  • Dépendances de bibliothèque : bibliothèques ou modules externes que votre projet et vos sous-projets incluent lors de la compilation
  • Outils (compilateurs, plug-ins et SDK qui traduisent votre source en une application ou une bibliothèque)
Créer des dépendances et leurs relations
Figure 1. Nouez des relations

Code source

Votre code source est le code Kotlin ou Java que vous écrivez dans votre application ou votre bibliothèque. (Pour en savoir plus sur l'utilisation de C++, consultez NDK Android.)

Le code source dépend des bibliothèques (y compris des bibliothèques d'exécution Kotlin et Java) et du SDK Android. Il nécessite le compilateur Kotlin ou Java correspondant.

Certains codes source contiennent des annotations qui nécessitent un traitement supplémentaire. Par exemple, si vous écrivez du code Jetpack Compose, vous ajoutez des annotations telles que @Composable qui doivent être traitées par le plug-in de compilation Kotlin Compose. Les autres annotations peuvent être traitées par un processeur de symboles Kotlin (KSP) ou des outils de traitement d'annotations distincts.

Dépendances des bibliothèques

Les bibliothèques contiennent du bytecode extrait dans votre application. Il peut s'agir d'un fichier JAR Java, d'une bibliothèque Android (AAR) ou d'un sous-projet de votre build. De nombreuses bibliothèques suivent la gestion sémantique des versions, qui peut vous aider à déterminer quand elles restent compatibles (ou non) lors de la mise à niveau.

La réutilisation des bibliothèques peut dépendre d'autres bibliothèques, appelée dépendance transitive. Cela réduit les dépendances que vous devez gérer explicitement : vous spécifiez celles que vous utilisez directement, et Gradle les extrait en même temps que ces dépendances transitives. Sachez que lorsque vous mettez à niveau vos dépendances directes, elles peuvent mettre à niveau ces dépendances transitives.

Parfois, une bibliothèque peut nécessiter des versions minimales du SDK Android au moment de l'exécution (minSdk) ou au moment de la compilation (compileSdk). Cela est nécessaire lorsqu'une bibliothèque utilise des fonctions incluses dans le SDK Android ou les API JDK fournies. La minSdk effective de votre application est la minSdk la plus élevée demandée par votre application et toutes ses dépendances de bibliothèques directes et transitives.

L'utilisation de certaines bibliothèques peut nécessiter l'utilisation d'un plug-in Gradle spécifique. Ces plug-ins d'assistance installent souvent des processeurs de symboles Kotlin ou d'autres processeurs d'annotations qui génèrent du code ou modifient la compilation de votre source pour vous permettre d'utiliser les fonctionnalités de la bibliothèque. Par exemple, Jetpack Room inclut des annotations et un KSP qui les transforme en code généré pour récupérer et modifier des données dans une base de données. Jetpack Compose nécessite le plug-in de compilation Compose pour modifier les fonctions annotées afin de gérer la façon et le moment où cette fonction est réexécutée.

Outils

Gradle

Gradle est l'outil de compilation qui lit vos fichiers de compilation et génère votre application ou votre bibliothèque. Il expose également une API permettant aux plug-ins d'étendre ses capacités. Gradle exécute plusieurs processus sur une ou plusieurs machines virtuelles Java, et ses plug-ins Java appellent les outils Java du JDK.

Plug-ins Gradle

Les plug-ins Gradle étendent Gradle en définissant de nouvelles tâches et de nouvelles configurations. L'application d'un plug-in à votre compilation active des fonctionnalités de compilation spécifiques, configurées en tant que données dans vos scripts de compilation. Pour les builds Android, le plug-in Gradle le plus important est le plug-in Android Gradle (AGP).

Compilateurs

Le compilateur Kotlin ou Java transforme votre code source en bytecode exécutable. Le compilateur Kotlin expose une API de plug-in qui permet d'exécuter l'analyse externe et la génération de code directement dans le compilateur, en accédant à la structure de code analysée.

Plug-ins du compilateur

Les plug-ins de compilation effectuent l'analyse et la génération de code à l'intérieur du compilateur Kotlin pendant que celui-ci analyse votre code. Ils sont installés lorsque vous appliquez leurs plug-ins Gradle au build.

SDK Android

Le SDK Android contient la plate-forme Android et les API Java pour une version spécifique d'Android, ainsi que les outils correspondants. Ces outils vous aident à gérer le SDK, à créer vos applications, et à communiquer avec et à émuler des appareils Android.

Chaque version du SDK Android fournit des API Java spécifiques auxquelles votre code source peut accéder, ainsi qu'une fonctionnalité de désugarisation pour utiliser ces API sur les versions antérieures d'Android.

JDK

Le kit de développement Java, qui contient des bibliothèques et des exécutables Java pour compiler le code source Java et exécuter des applications Java. Plusieurs JDK sont en jeu dans un build Android. Pour en savoir plus, consultez Versions de Java dans les builds Android.

Champs d'application Gradle

Gradle regroupe les dépendances de bibliothèques dans différents champs d'application (appelés configurations dans l'API Gradle), ce qui vous permet de spécifier différents ensembles de dépendances de bibliothèques à utiliser dans différentes parties de votre compilation. Par exemple, vous ne souhaitez probablement pas inclure de bibliothèques de test telles que JUnit dans votre application ou bibliothèque publiée, mais vous en avez besoin lorsque vous créez et exécutez vos tests unitaires. Vous utilisez également des portées pour ajouter des processeurs de symboles ou d'annotations afin d'analyser votre code.

Par exemple, AGP définit les champs d'application implementation et api, qui vous permettent de spécifier si une dépendance doit être exposée aux utilisateurs de votre sous-projet. Consultez Configurer les dépendances pour obtenir une description de ces champs d'application et des autres champs d'application utilisés dans un build Android.

Ajoutez des dépendances de bibliothèque dans le bloc dependencies de vos fichiers de compilation, sous forme de chaînes group:artifact:version:

Kotlin

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation("com.example:library1:1.2.3")
    api("com.example:library2:1.1.1")
}

Groovy

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation 'com.example:library1:1.2.3'
    api 'com.example:library2:1.1.1'
}

ou dans un catalogue de versions:

# Version catalog - gradle/libs.versions.toml
[versions]
exampleLib = "1.2.3"
examplePlugin = "2.3.4"

[libraries]
example-library = { group = "com.example", name = "library", version.ref = "exampleLib" }

[plugins]
example-plugin = { id = "com.example.plugin", version.ref = "examplePlugin" }

et spécifiez les variables générées dans vos fichiers de compilation:

Kotlin

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation(libs.example.library)
}

Groovy

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation libs.example.library
}