Vos fichiers de compilation spécifient vos dépendances directes, mais chacune de ces dépendances peut en nécessiter d'autres. Ces dépendances transitives augmentent rapidement votre graphique des dépendances global, souvent avec des versions en conflit.
Lorsque les parties minor
(nouvelles fonctionnalités) ou patch
(corrections de bugs) changent, la bibliothèque est toujours susceptible d'être compatible et moins susceptible d'avoir un impact sur votre application.
Par exemple, supposons que votre application dépende des bibliothèques A et B, qui dépendent à leur tour de différentes versions de la bibliothèque C.
Dans ce cas, Gradle choisit la dernière version de la bibliothèque C par défaut, ce qui peut entraîner des problèmes de compilation ou d'exécution. Dans cet exemple, la bibliothèque C est résolue en 2.1.1, mais notez que la bibliothèque A a demandé la bibliothèque C 1.0.3. La partie principale du numéro de version a changé, ce qui indique des modifications incompatibles, telles que des fonctions ou des types supprimés. Cela peut entraîner le plantage des appels passés depuis la bibliothèque A.
Votre application peut avoir des dépendances directes qui sont également des dépendances transitives.
Dans ce cas, les dépendances transitives plus récentes peuvent remplacer la version que vous demandez directement dans votre application.
Gradle examine toutes les versions candidates pour toutes les dépendances du graphique afin de déterminer la version la plus récente de chaque dépendance. Vous pouvez utiliser des tâches Gradle de base et des outils plus avancés pour déterminer les versions de chaque dépendance que Gradle a résolues. Il est essentiel de comparer les modifications apportées à cette résolution pour comprendre et atténuer les risques de votre mise à niveau.
Par exemple, vous pouvez utiliser la tâche Gradle dependencies
en exécutant ./gradlew
app:dependencies
pour afficher un arbre de toutes les dépendances utilisées par votre module d'application. Si nous l'exécutons avec une application qui utilise les bibliothèques, comme illustré dans la figure 2,
1: releaseRuntimeClasspath - Runtime classpath of /release.
2: +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0
3: | +--- ... (omitted for brevity) ...
4: +--- com.sample:library.a:1.2.3
5: | +--- com.sample:library.c:2.1.1
6: | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
7: | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
8: +--- com.sample:library.c:1.4.1 -> 2.1.1 (*)
Cette partie du rapport présente certaines des dépendances résolues pour la configuration releaseRuntimeClasspath
.
Chaque fois que ->
apparaît dans votre rapport sur les dépendances, un demandeur (votre application ou une autre bibliothèque) utilise une version de cette dépendance qu'il n'attend pas. Dans de nombreux cas, cela ne pose aucun problème, car la plupart des bibliothèques sont écrites pour assurer la rétrocompatibilité. Toutefois, certaines bibliothèques peuvent apporter des modifications incompatibles, et ce rapport peut vous aider à déterminer d'où proviennent les nouveaux problèmes liés au comportement de votre application.
Pour en savoir plus sur l'utilisation des rapports sur les dépendances de Gradle, consultez Afficher et déboguer les dépendances.
Vous pouvez spécifier les versions demandées directement, dans un catalogue de versions ou dans une nomenclature.
Résolution de la spécification de version directe
Les versions des dépendances que vous spécifiez deviennent des candidats pour la résolution de version.
Par exemple, pour demander la version 1.7.3 de la bibliothèque androidx.compose.ui:ui
en tant que dépendance dans votre app/build.gradle.kts
:
dependencies {
implementation("androidx.compose.ui:ui:1.7.3")
}
La version 1.7.3 devient une version candidate. Gradle se résout vers la dernière version parmi les versions 1.7.3 et autres de la même bibliothèque demandées par les dépendances transitives.
Résolution du catalogue de versions
Les catalogues de versions définissent des variables pour suivre la version des dépendances utilisées dans l'ensemble de votre application. Si vous utilisez une variable du catalogue de versions, les dépendances spécifiées de cette variable sont ajoutées aux candidats à la résolution de version. Les variables inutilisées du catalogue de versions sont ignorées.
Par exemple, pour spécifier la version 1.7.3 de androidx.compose.ui:ui
comme dépendance dans votre fichier gradle/libs.versions.toml
:
[versions]
ui = "1.7.3"
[libraries]
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "ui" }
Cela définit une variable nommée libs.androidx.compose.ui
pour représenter la bibliothèque. Cette version n'est pas considérée comme une candidate, sauf si vous utilisez cette variable pour spécifier une dépendance.
Pour demander la bibliothèque et sa version dans votre app/build.gradle.kts
:
dependencies {
implementation(libs.androidx.compose.ui)
}
Gradle résout le problème de la même manière que pour une spécification directe.
Résolution de la nomenclature
Les versions de toutes les bibliothèques figurant dans la nomenclature deviennent candidates à la résolution de version. Notez que les bibliothèques ne sont utilisées en tant que dépendances que si elles sont spécifiées comme directes ou indirectes. Les autres bibliothèques de la nomenclature sont ignorées.
Les versions de la nomenclature affectent vos dépendances directes, ainsi que toutes les dépendances transitives qui apparaissent dans la nomenclature.
Par exemple, spécifiez une nomenclature comme dépendance plate-forme dans votre app/build.gradle.kts
:
dependencies {
implementation(platform("androidx.compose:compose-bom:2024.10.00"))
implementation("androidx.compose.ui:ui")
}
Les bibliothèques que vous souhaitez utiliser comme dépendances ne nécessitent pas de spécification de version. La version demandée provient de la nomenclature.
Notez que vous pouvez également utiliser un catalogue de versions pour créer des variables pour la nomenclature et les bibliothèques. Omettre les numéros de version dans le catalogue de versions pour les bibliothèques qui apparaissent dans une dépendance de nomenclature.
Par exemple, votre catalogue de versions contient la nomenclature et son numéro de version, mais ne spécifie pas de version pour les bibliothèques que vous référencez à partir de la nomenclature :
[versions]
composeBom = "2024.10.00"
[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
Votre app/build.gradle.kts
fait référence à la nomenclature et aux bibliothèques à l'aide des variables définies dans le catalogue de versions :
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
}
La version de cette bibliothèque spécifiée dans la nomenclature devient une candidate pour la résolution de Gradle. En outre, toutes les autres versions de bibliothèque spécifiées dans la nomenclature deviennent des versions candidates, que vous les utilisiez ou non directement en tant que dépendances.
Par exemple, supposons qu'une nomenclature spécifie des versions pour les bibliothèques A, B et C. Votre application souhaite utiliser directement la bibliothèque A en tant que dépendance, ainsi que la bibliothèque D. La bibliothèque D utilise la bibliothèque B comme dépendance. Rien n'utilise la bibliothèque C.
Les bibliothèques A, B et D sont des dépendances dans l'application. La bibliothèque C est ignorée. Gradle utilise les versions d'A et de B spécifiées dans la nomenclature comme candidates, même si vous ne spécifiez pas directement la bibliothèque B comme dépendance.
Si la bibliothèque D a demandé une version de la bibliothèque B antérieure à la version 2.0.1, Gradle résout le problème en version 2.0.1. Si la bibliothèque D a demandé une version supérieure de la bibliothèque B, Gradle résout cette version.