In Ihren Build-Dateien werden Ihre direkten Abhängigkeiten angegeben. Jede dieser Abhängigkeiten kann jedoch andere erfordern. Diese transitiven Abhängigkeiten führen schnell zu einem großen Abhängigkeitsdiagramm, oft mit in Konflikt stehenden Versionen.
Wenn sich die Teile minor
(neue Funktionen) oder patch
(Fehlerkorrekturen) ändern, ist die Bibliothek wahrscheinlich weiterhin kompatibel und hat weniger Auswirkungen auf Ihre Anwendung.
Angenommen, Ihre Anwendung hängt von Bibliothek A und Bibliothek B ab, die wiederum von verschiedenen Versionen der Bibliothek C abhängen.
In diesem Fall wählt Gradle standardmäßig die neueste Version der Bibliothek C aus, was zu Kompilierungs- oder Laufzeitproblemen führen kann. In diesem Beispiel wird Bibliothek C auf 2.1.1 aufgelöst. Beachten Sie jedoch, dass Bibliothek A Bibliothek C 1.0.3 angefordert hat. Der Hauptteil der Versionsnummer hat sich geändert, was auf inkompatible Änderungen hinweist, z. B. entfernte Funktionen oder Typen. Dies kann dazu führen, dass Aufrufe aus Bibliothek A abstürzen.
Ihre App kann direkte Abhängigkeiten haben, die auch transitive Abhängigkeiten sind.
In einem solchen Fall können neuere transitive Abhängigkeiten die Version überschreiben, die Sie direkt in Ihrer App anfordern.
Gradle prüft alle Kandidatenversionen für alle Abhängigkeiten im Diagramm, um die neueste Version jeder Abhängigkeit zu ermitteln. Mit einfachen Gradle-Aufgaben und erweiterten Tools können Sie ermitteln, welche Versionen der einzelnen Abhängigkeiten von Gradle aufgelöst wurden. Der Vergleich der Änderungen in dieser Auflösung ist entscheidend, um die Risiken des Upgrades zu verstehen und zu minimieren.
Sie können beispielsweise die Gradle-Aufgabe dependencies
verwenden, indem Sie ./gradlew
app:dependencies
ausführen, um einen Baum aller Abhängigkeiten anzuzeigen, die von Ihrem App-Modul verwendet werden. Wenn wir diesen Test auf eine Anwendung anwenden, die die Bibliotheken wie in Abbildung 2 gezeigt verwendet, sehen wir
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 (*)
In diesem Teil des Berichts sind einige der Abhängigkeiten aufgeführt, die für die releaseRuntimeClasspath
-Konfiguration behoben wurden.
Wenn Sie in Ihrem Abhängigkeitsbericht ->
sehen, verwendet ein Anfragender (Ihre Anwendung oder eine andere Bibliothek) eine Version dieser Abhängigkeit, die nicht erwartet wird. In vielen Fällen führt dies zu keinen Problemen, da die meisten Bibliotheken für die Abwärtskompatibilität geschrieben sind. Einige Bibliotheken können jedoch inkompatible Änderungen vornehmen. Anhand dieses Berichts können Sie ermitteln, woher neue Probleme mit dem Verhalten Ihrer Anwendung stammen.
Weitere Informationen zur Verwendung der Abhängigkeitsberichte von Gradle finden Sie unter Abhängigkeiten ansehen und debuggen.
Sie können angeforderte Versionen direkt, in einem Versionskatalog oder in einer Stückliste angeben.
Auflösung der Spezifikation für direkte Version
Die von Ihnen angegebenen Versionen von Abhängigkeiten werden als Kandidaten für die Versionsauflösung ausgewählt.
So fordern Sie beispielsweise Version 1.7.3 der androidx.compose.ui:ui
-Bibliothek als Abhängigkeit in Ihrer app/build.gradle.kts
an:
dependencies {
implementation("androidx.compose.ui:ui:1.7.3")
}
Version 1.7.3 wird zur Release-Kandidatenversion. Gradle löst die neueste Version zwischen 1.7.3 und anderen Versionen derselben Bibliothek auf, die durch transitive Abhängigkeiten angefordert wird.
Versionskatalogauflösung
In Versionskatalogen werden Variablen definiert, um die Version der Abhängigkeiten zu erfassen, die in Ihrer Anwendung verwendet werden. Wenn Sie eine Variable aus dem Versionskatalog verwenden, werden die angegebenen Abhängigkeiten dieser Variablen den Kandidaten für die Versionsauflösung hinzugefügt. Nicht verwendete Variablen im Versionskatalog werden ignoriert.
So geben Sie beispielsweise Version 1.7.3 der androidx.compose.ui:ui
als Abhängigkeit in Ihrer gradle/libs.versions.toml
-Datei an:
[versions]
ui = "1.7.3"
[libraries]
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "ui" }
Dadurch wird eine Variable namens libs.androidx.compose.ui
für die Bibliothek definiert. Diese Version wird nicht als Kandidat betrachtet, es sei denn, Sie verwenden diese Variable, um eine Abhängigkeit anzugeben.
So fordern Sie die Bibliothek und ihre Version in Ihrer app/build.gradle.kts
an:
dependencies {
implementation(libs.androidx.compose.ui)
}
Gradle führt die Auflösung auf die gleiche Weise durch wie bei einer direkten Spezifikation.
Auflösung der Stückliste
Versionen für alle Bibliotheken, die in der BOM aufgeführt sind, werden als Kandidaten für die Versionsauflösung ausgewählt. Bibliotheken werden nur dann als Abhängigkeiten verwendet, wenn sie als direkt oder indirekt angegeben sind. Andere Bibliotheken in der BOM werden ignoriert.
BOM-Versionen wirken sich auf Ihre direkten Abhängigkeiten sowie auf alle transitiven Abhängigkeiten aus, die in der BOM aufgeführt sind.
Geben Sie beispielsweise eine BOM als Plattformabhängigkeit in Ihrer app/build.gradle.kts
an:
dependencies {
implementation(platform("androidx.compose:compose-bom:2024.10.00"))
implementation("androidx.compose.ui:ui")
}
Für Bibliotheken, die Sie als Abhängigkeiten verwenden möchten, ist keine Versionsangabe erforderlich. Die angeforderte Version stammt aus der BOM.
Sie können auch einen Versionskatalog verwenden, um Variablen für die BOM und Bibliotheken zu erstellen. Lassen Sie die Versionsnummern im Versionskatalog für Bibliotheken aus, die in einer BOM-Abhängigkeit enthalten sind.
Ihr Versionskatalog enthält beispielsweise die BOM und ihre Versionsnummer, aber keine Version für die Bibliotheken, auf die Sie in der BOM verweisen:
[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" }
In Ihrem app/build.gradle.kts
wird auf die BOM und die Bibliotheken mithilfe der im Versionskatalog definierten Variablen verwiesen:
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
}
Die in der BOM angegebene Version dieser Bibliothek wird als Kandidat für die Auflösung von Gradle ausgewählt. Außerdem werden alle anderen im BOM angegebenen Bibliotheksversionen zu Kandidatenversionen, unabhängig davon, ob Sie sie direkt als Abhängigkeiten verwenden.
Angenommen, in einer BOM werden Versionen für die Bibliotheken A, B und C angegeben. Ihre Anwendung soll Bibliothek A und Bibliothek D direkt als Abhängigkeit verwenden. Bibliothek D verwendet Bibliothek B als Abhängigkeit. Bibliothek C wird von nichts verwendet.
Die Bibliotheken A, B und D sind Abhängigkeiten in der Anwendung. Bibliothek C wird ignoriert. Gradle verwendet die in der BOM angegebenen Versionen von A und B als Kandidaten, auch wenn Sie Bibliothek B nicht direkt als Abhängigkeit angeben.
Wenn Bibliothek D eine Version von Bibliothek B anfordert, die niedriger als 2.0.1 ist, wird 2.0.1 von Gradle ermittelt. Wenn Bibliothek D eine höhere Version von Bibliothek B angefordert hat, wird diese Version von Gradle ermittelt.