Wenn Sie eine Abhängigkeit hinzufügen, können Probleme mit erforderlichen Abhängigkeiten auftreten durch die ursprüngliche Abhängigkeit und Konflikte zwischen verschiedenen Abhängigkeitsversionen. So analysieren Sie Ihr Abhängigkeitsdiagramm und beheben häufige Probleme.
Informationen zum Beheben von Fehlern bei der Abhängigkeitsauflösung, die einen benutzerdefinierten Build betreffen Logik, siehe Benutzerdefinierte Strategien zur Auflösung von Abhängigkeiten.
Modulabhängigkeiten ansehen
Für einige direkte Abhängigkeiten können eigene Abhängigkeiten gelten. Diese werden als transitive Abhängigkeiten. Anstatt jedes einzelne Element manuell zu deklarieren, werden diese automatisch erfasst und hinzugefügt. Das Android-Plug-in für Gradle stellt eine Aufgabe bereit, die eine Liste der Abhängigkeiten, die Gradle für ein bestimmtes Modul auflöst.
Für jedes Modul enthält der Bericht gruppiert auch die Abhängigkeiten nach Build-Variante, Testquellensatz und classpath zurück. Im Folgenden finden Sie einen Beispielbericht für die Laufzeit eines App-Moduls classpath seiner Debug-Build-Variante und Compile-Klassenpfad seiner instrumentierten Testquellensatz.
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
...
So führen Sie die Aufgabe aus:
- Wählen Sie Ansicht > Tool-Fenster > Gradle (oder klicken Sie auf Gradle in der Leiste des Toolfensters.
- Maximieren AppName > Tasks > android und doppelklicken Sie auf androidDependencies. Nach der Ausführung von Gradle der Aufgabe sollte das Fenster Ausführen geöffnet werden, damit die Ausgabe angezeigt wird.
Weitere Informationen zum Verwalten von Abhängigkeiten in Gradle finden Sie unter Grundlagen des Abhängigkeitsmanagements im Gradle-Nutzerhandbuch.
Transitive Abhängigkeiten ausschließen
Wenn der Umfang einer Anwendung zunimmt, kann sie eine Reihe von Abhängigkeiten enthalten, darunter:
direkte Abhängigkeiten und transitive Abhängigkeiten (Bibliotheken,
Importierte Bibliotheken hängen.
Zum Ausschließen von transitiven Abhängigkeiten, die Sie nicht mehr benötigen, können Sie die Methode
exclude
Keyword wie unten angegeben:
Kotlin
dependencies { implementation("some-library") { exclude(group = "com.example.imgtools", module = "native") } }
Cool
dependencies { implementation('some-library') { exclude group: 'com.example.imgtools', module: 'native' } }
Transitive Abhängigkeiten von Testkonfigurationen ausschließen
Wenn Sie bestimmte transitive Abhängigkeiten aus Ihren Tests ausschließen müssen,
funktioniert das obige Codebeispiel möglicherweise nicht wie erwartet. Das liegt daran, dass ein Test
Konfiguration (z.B. androidTestImplementation
) erweitert die
implementation
-Konfiguration. Das heißt, sie enthält immer implementation
.
wenn Gradle die Konfiguration auflöst.
Um transitive Abhängigkeiten aus Ihren Tests auszuschließen, ausgeführt werden:
Kotlin
android.testVariants.all { compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") }
Cool
android.testVariants.all { variant -> variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' }
Hinweis:Sie können das Keyword exclude
weiterhin verwenden.
im Abhängigkeiten-Block, wie im ursprünglichen Codebeispiel aus der
Transitive Abhängigkeiten ausschließen
Abschnitt zum Weglassen von transitiven Abhängigkeiten, die für den Test spezifisch sind
und sind nicht in anderen Konfigurationen enthalten.
Fehler bei der Abhängigkeitsauflösung beheben
Wenn Sie Ihrem App-Projekt mehrere Abhängigkeiten hinzufügen, werden diese direkten und transitive Abhängigkeiten, die miteinander in Konflikt stehen. Der Android-Gradle-Plug-in versucht das Plug-in, diese Konflikte ordnungsgemäß zu lösen. Einige Konflikte können jedoch dazu führen, um Zeit- oder Laufzeitfehler zu kompilieren.
Damit Sie besser untersuchen können, welche Abhängigkeiten zu Fehlern beitragen, prüfen Sie die Abhängigkeitsstruktur Ihrer App und suchen Sie Abhängigkeiten, die mehr als einmal oder mit in Konflikt stehenden Versionen auftreten.
Wenn Sie die doppelte Abhängigkeit nicht leicht identifizieren können, versuchen Sie es mit Android Über die Benutzeroberfläche von Studio, um nach Abhängigkeiten zu suchen, die die duplizierte Klasse enthalten wie folgt:
- Wählen Sie Navigation > Class aus.
- Vergewissern Sie sich im Pop-up-Suchdialogfeld, dass das Kontrollkästchen neben Das Kästchen Nicht-Projektelemente einschließen ist angeklickt.
- Geben Sie den Namen der Klasse ein, der im Build-Fehler angezeigt wird.
- Überprüfen Sie die Ergebnisse für die Abhängigkeiten, in denen die Klasse enthalten ist.
In den folgenden Abschnitten werden die verschiedenen Arten der Abhängigkeitsauflösung beschrieben und wie Sie diese beheben können.
Doppelte Kursfehler beheben
Wenn eine Klasse mehrmals im Klassenpfad zur Laufzeit vorhanden ist, erhalten Sie den Fehler in etwa so:
Program type already present com.example.MyClass
Dieser Fehler tritt normalerweise aus einem der folgenden Gründe auf:
- Eine binäre Abhängigkeit umfasst eine Bibliothek, die Ihre App auch als
direkte Abhängigkeit. Beispiel: Ihre App deklariert eine direkte Abhängigkeit von
Bibliothek A und Bibliothek B, aber Bibliothek A enthält bereits Bibliothek B in
binär.
- Um dieses Problem zu beheben, entfernen Sie Bibliothek B als direkte Abhängigkeit.
- Ihre App hat eine lokale Binärabhängigkeit und eine binäre Remote-Abhängigkeit vom
aus derselben Bibliothek.
- Um dieses Problem zu beheben, entfernen Sie eine der binären Abhängigkeiten.
Konflikte zwischen Klassenpfaden beheben
Wenn Gradle den Compiler-Klassenpfad auflöst, wird zuerst die runtime aufgelöst classpath und bestimmt anhand des Ergebnisses, welche Versionen von Abhängigkeiten dem Compiler-Klassenpfad hinzugefügt werden. Mit anderen Worten, die Laufzeit classpath bestimmt die erforderlichen Versionsnummern für identische Abhängigkeiten von nachgelagerte Klassenpfade.
Der Laufzeit-Klassenpfad Ihrer App bestimmt auch die Versionsnummern, die Gradle für den Abgleich von Abhängigkeiten im Laufzeit-Klassenpfad für den Anwendungstest APK Die Hierarchie der Klassenpfade ist in Abbildung 1 dargestellt.
Ein Konflikt, bei dem verschiedene Versionen derselben Abhängigkeit auf
können mehrere Klassenpfade auftreten, wenn Ihre App beispielsweise eine Version
eine Abhängigkeit unter Verwendung von implementation
Abhängigkeitskonfiguration
und ein Bibliotheksmodul eine andere Version der Abhängigkeit enthält,
runtimeOnly
-Konfiguration.
Beim Auflösen von Abhängigkeiten von der Laufzeit und Kompilieren von Zeitklassenpfaden Das Gradle-Plug-in 3.3.0 und höher versucht, bestimmte Downstream-Vorgänge automatisch zu korrigieren Versionskonflikte auftreten. Wenn der Laufzeit-Klassenpfad z. B. die Bibliothek A enthält, Version 2.0 und der Kompilierungsklassenpfad enthält Library A Version 1.0, das Plug-in aktualisiert die Abhängigkeit vom kompilierten Klassenpfad automatisch auf Bibliothek A Version 2.0, um Fehler zu vermeiden.
Wenn der Laufzeit-Klassenpfad jedoch Bibliothek A Version 1.0 enthält und die Kompilierung classpath Version 2.0 der Bibliothek A enthält, führt das Plug-in kein Downgrade der vom Kompilierungsklassenpfad zu Bibliothek A Version 1.0. erhalten Sie einen Fehler wie diesen:
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.
Führen Sie einen der folgenden Schritte aus, um das Problem zu beheben:
- Nehmen Sie die gewünschte Version der Abhängigkeit als
api
-Abhängigkeit in Ihr Bibliotheksmodul. Das heißt, nur Ihr Bibliotheksmodul deklariert die Abhängigkeit, aber hat das App-Modul auch vorübergehend Zugriff auf seine API. - Alternativ können Sie die Abhängigkeit in beiden Modulen deklarieren. Sie sollten jedoch dass jedes Modul dieselbe Version der Abhängigkeit verwendet. Erwägen Sie Projektweite Attribute konfigurieren um sicherzustellen, dass die Versionen jeder Abhängigkeit im gesamten Projekt einheitlich bleiben.