Podczas dodawania zależności mogą wystąpić problemy z wymaganymi zależnościami w oparciu o pierwotną zależność i powodują konflikty między różnymi wersjami zależności. Poniżej znajdziesz informacje o tym, jak przeanalizować graf zależności i rozwiązać typowe problemy.
Wskazówki dotyczące naprawiania błędów związanych z rozwiązywaniem zależności, które obejmują kompilację niestandardową logiki logicznej, zobacz Niestandardowe strategie rozwiązywania problemów z zależnościami.
Wyświetl zależności modułu
Niektóre bezpośrednie zależności mogą mieć własne zależności. Są to tzw. zależności przejściowe. Zamiast wymagać ręcznego deklarowania każdego tagu zależność przejściowa, Gradle automatycznie je zbiera i dodaje. Wtyczka Androida do Gradle udostępnia zadanie, które wyświetla listę które rozwiązuje Gradle w przypadku danego modułu.
Raport w każdym module grupuje też zależności na podstawie wariantu kompilacji, testowego zbioru źródeł classpath. Poniżej znajdziesz przykładowy raport dotyczący czasu działania modułu aplikacji ścieżka klasy jego wariantu kompilacji do debugowania i skompiluj ścieżkę klasy jej ścieżki instrumentacji, testowym zestawem źródeł źródłowych.
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
...
Aby uruchomić zadanie, wykonaj te czynności:
- Wybierz Widok > Okna narzędziowe > Gradle (lub kliknij Gradle na pasku okien narzędzi).
- Rozwiń sekcję AppName > Lista zadań > android i kliknij dwukrotnie androidDependencies. Po uruchomieniu Gradle powinno się otworzyć okno Uruchom, aby wyświetlić dane wyjściowe.
Więcej informacji o zarządzaniu zależnościami w Gradle znajdziesz w artykule Podstawowe informacje o zarządzaniu zależnościami w przewodniku użytkownika Gradle.
Wyklucz zależności pośrednie
W miarę rozwoju aplikacji może zawierać szereg zależności, w tym:
zależności bezpośrednie i pośrednie (biblioteki,
między importowanymi bibliotekami).
Aby wykluczyć pośrednie zależności, których już nie potrzebujesz, możesz użyć funkcji
exclude
słowo kluczowe podane poniżej:
Kotlin
dependencies { implementation("some-library") { exclude(group = "com.example.imgtools", module = "native") } }
Odlotowe
dependencies { implementation('some-library') { exclude group: 'com.example.imgtools', module: 'native' } }
Wyklucz zależności pośrednie z konfiguracji testów
Jeśli chcesz wykluczyć z testów określone zależności pośrednie,
powyższy przykładowy kod może nie działać zgodnie z oczekiwaniami. To dlatego, że test
konfiguracji (np. androidTestImplementation
) powoduje rozszerzenie modułu
Konfiguracja implementation
. Oznacza to, że zawsze zawiera ona ciąg implementation
gdy Gradle rozwiązuje konfigurację.
Aby wykluczyć z testów zależności pośrednie, musisz to zrobić na stronie czas wykonania, jak poniżej:
Kotlin
android.testVariants.all { compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") }
Odlotowe
android.testVariants.all { variant -> variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' }
Uwaga: nadal możesz używać słowa kluczowego exclude
.
w bloku zależności zgodnie z oryginalnym przykładowym kodem
Wyklucz zależności pośrednie
aby pominąć zależności przejściowe, które są specyficzne dla testu
i nie są uwzględniane w innych konfiguracjach.
Naprawianie błędów związanych z rozwiązywaniem zależności
Gdy dodasz do projektu aplikacji wiele zależności, pośrednie zależności mogą ze sobą kolidować. Gradle Androida próbuje bezproblemowo rozwiązać te konflikty, ale niektóre konflikty mogą kompilować błędy czasu lub czasu działania.
Aby dowiedzieć się, które zależności przyczyniają się do powstawania błędów, sprawdź drzewo zależności aplikacji i wyszukaj które występują więcej niż raz lub mają wersje powodujące konflikty.
Jeśli nie możesz łatwo zidentyfikować zduplikowanej zależności, spróbuj użyć Androida interfejsu użytkownika Studio do wyszukiwania zależności zawierających zduplikowaną klasę; w następujący sposób:
- Wybierz Nawigacja > Zajęcia na pasku menu.
- Upewnij się, że w wyskakującym okienku wyszukiwania pole obok Opcja Uwzględnij elementy niebędące projektami jest zaznaczona.
- Wpisz nazwę klasy, która pojawi się w komunikacie o błędzie kompilacji.
- Sprawdź wyniki pod kątem zależności, które obejmują klasę.
W poniższych sekcjach opisano różne typy rozwiązywania zależności możliwych błędów i sposobów ich naprawy.
Naprawianie błędów związanych z duplikatami zajęć
Jeśli w ścieżce środowiska wykonawczego klasa występuje więcej niż raz, otrzymasz podobny do tego:
Program type already present com.example.MyClass
Ten błąd występuje zwykle w jednej z tych przyczyn:
- Zależność binarna obejmuje bibliotekę, którą aplikacja zawiera jako
zależności bezpośredniej. Na przykład aplikacja deklaruje bezpośrednią zależność od
Biblioteka A i B, ale Biblioteka A obejmuje już Bibliotekę B
binarny.
- Aby rozwiązać ten problem, usuń Bibliotekę B jako zależność bezpośrednią.
- Aplikacja ma lokalną zależność binarną oraz zdalną zależność binarną
w tej samej bibliotece.
- Aby rozwiązać ten problem, usuń jedną z zależności binarnych.
Rozwiązywanie konfliktów między ścieżkami zajęć
Gdy Gradle rozpozna ścieżkę klasy kompilacji, najpierw rozstrzygnie środowisko wykonawcze classpath i używa wyniku do określenia, które wersje zależności powinny być zostaną dodane do ścieżki klasy kompilacji. Innymi słowy, środowisko wykonawcze classpath określa wymagane numery wersji dla identycznych zależności ścieżek klasowych.
Ścieżka klasy środowiska wykonawczego aplikacji określa też numery wersji, które Gradle wymaga dopasowania zależności w ścieżce klasy środowiska wykonawczego na potrzeby testu aplikacji plik APK. Hierarchia ścieżek klas została opisana na rysunku 1.
Konflikt, w którym występują różne wersje tej samej zależności
wiele ścieżek klas może wystąpić, gdy na przykład aplikacja zawiera wersję
zależność z użyciem funkcji implementation
konfiguracja zależności
a moduł biblioteki zawiera inną wersję zależności
Konfiguracja runtimeOnly
.
Podczas rozwiązywania zależności od środowiska wykonawczego i kompilowania ścieżek klas czasowych, Android Wtyczka Gradle w wersji 3.3.0 lub nowszej próbuje automatycznie naprawić niektóre z kolejnych żądań i konflikty wersji. Jeśli na przykład ścieżka klasy środowiska wykonawczego zawiera Bibliotekę A 2.0, a ścieżka klasy kompilacji zawiera Bibliotekę A w wersji 1.0, automatycznie aktualizuje zależność w ścieżce klasy kompilacji do biblioteki A wersji 2.0, by uniknąć błędów.
Jeśli jednak ścieżka klasy środowiska wykonawczego zawiera bibliotekę A w wersji 1.0 i narzędzie classpath obejmuje Bibliotekę A w wersji 2.0, wtyczka nie zmienia w bibliotece A w wersji 1.0, a mimo to podobny błąd:
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.
Aby rozwiązać ten problem, wykonaj jedną z tych czynności:
- Uwzględnij żądaną wersję zależności jako zależność
api
w elemencie z biblioteki. Oznacza to, że tylko moduł biblioteki deklaruje zależność, moduł aplikacji będzie też pośrednio korzystać ze swojego interfejsu API. - Możesz też zadeklarować zależność w obu modułach, ale sprawdź, czy każdy moduł używa tej samej wersji zależności. Rozważ konfigurowanie właściwości na poziomie projektu aby wersje każdej zależności były spójne w całym projekcie.