Dodaj zależności kompilacji

System kompilacji Gradle w Android Studio pozwala dodawać do kompilacji zewnętrzne pliki binarne lub inne moduły biblioteki jako zależności. Zależności mogą być zlokalizowane na Twoim komputerze lub w repozytorium zdalnym, a wszystkie deklarowane zależności przejściowe również są uwzględniane automatycznie. Na tej stronie opisujemy, jak używać zależności w projekcie na Androida, w tym szczegóły zachowania i konfiguracji związane z wtyczką Androida do obsługi Gradle (AGP). Bardziej koncepcyjny przewodnik po zależnościach Gradle znajdziesz też w przewodniku Gradle dotyczącym zarządzania zależnościami. Pamiętaj jednak, że Twój projekt na Androida musi korzystać tylko z konfiguracji zależności zdefiniowanych na tej stronie.

Dodawanie zależności biblioteki lub wtyczki

Najlepszy sposób dodawania zależności kompilacji i zarządzania nimi to użycie katalogów wersji – metody, która jest domyślnie używana w nowych projektach. W tej sekcji omawiamy najpopularniejsze typy konfiguracji stosowane w projektach na Androida. Więcej opcji znajdziesz w dokumentacji Gradle. Przykład aplikacji korzystającej z katalogów wersji znajdziesz w artykule Now in Android. Jeśli masz już zależności kompilacji skonfigurowane bez katalogów wersji i masz projekt z wieloma modułami, zalecamy przeniesienie.

Wskazówki dotyczące dodawania zależności natywnych i zarządzania nimi (niezbyt częste) znajdziesz w artykule Zależności natywne.

W tym przykładzie dodajemy do naszego projektu zdalną zależność binarną (biblioteka Jetpack Macrobenchmark), zależność modułu lokalnej biblioteki (myLibrary) oraz zależność wtyczki (wtyczka Androida do Gradle). Oto ogólne czynności, które pozwalają dodać te zależności do projektu:

  1. Dodaj alias dla odpowiedniej wersji zależności w sekcji [versions] pliku katalogu wersji o nazwie libs.versions.toml (w katalogu gradle w widoku Projekt lub w widoku Skrypty Gradle w widoku Androida):

    [versions]
    agp = "8.3.0"
    androidx-macro-benchmark = "1.2.2"
    my-library = "1.4"
    
    [libraries]
    ...
    
    [plugins]
    ...
    

    Aliasy mogą zawierać łączniki lub podkreślenia. Aliasy te generują zagnieżdżone wartości, do których możesz się odwoływać w skryptach kompilacji. Odwołania zaczynają się od nazwy katalogu, czyli części libs elementu libs.versions.toml. Jeśli korzystasz z katalogu z jedną wersją, zalecamy zachowanie domyślnej wartości „libs”.

  2. Dodaj alias zależności w sekcji [libraries] (na potrzeby zdalnych plików binarnych lub modułów biblioteki lokalnej) lub [plugins] (w przypadku wtyczek) pliku libs.versions.toml.

    [versions]
    ...
    
    [libraries]
    androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidx-macro-benchmark" }
    my-library = { group = "com.myapplication", name = "mylibrary", version.ref = "my-library" }
    
    [plugins]
    androidApplication = { id = "com.android.application", version.ref = "agp" }
    

    Niektóre biblioteki są dostępne w opublikowanym zestawieniu materiałów (BOM), który grupuje rodziny bibliotek i ich wersje. Możesz dodać BOM do katalogu wersji i plików kompilacji, a następnie pozwolić mu zarządzać tymi wersjami za Ciebie. Więcej informacji znajdziesz w artykule Korzystanie z listy materiałów.

  3. Dodaj odwołanie do aliasu zależności do skryptu kompilacji modułów, które wymagają tej zależności. Przekonwertuj podkreślenia i myślniki aliasu na kropki, gdy odwołujesz się do niego w skrypcie kompilacji. Nasz skrypt kompilacji na poziomie modułu wyglądałby tak:

    Kotlin

    plugins {
      alias(libs.plugins.androidApplication)
    }
    
    dependencies {
      implementation(libs.androidx.benchmark.macro)
      implementation(libs.my.library)
    }
    

    Odlotowy

    plugins {
      alias 'libs.plugins.androidApplication'
    }
    
    dependencies {
      implementation libs.androidx.benchmark.macro
      implementation libs.my.library
    }
    

    Odwołania do wtyczki zawierają ciąg plugins po nazwie katalogu, a odwołania do wersji zawierają po nazwie katalogu ciąg versions (odniesienia do wersji są rzadkie; przykłady odwołań do wersji znajdziesz w sekcji Zależności z takimi samymi numerami wersji). Pliki referencyjne nie zawierają kwalifikatora libraries, więc nie możesz użyć słowa versions ani plugins na początku aliasu biblioteki.

Skonfiguruj zależności

W bloku dependencies możesz zadeklarować zależność biblioteki, korzystając z jednej z kilku różnych konfiguracji zależności (np. implementation przedstawionych wcześniej). Każda konfiguracja zależności udostępnia Gradle inne instrukcje dotyczące korzystania z zależności. W tabeli poniżej opisujemy poszczególne konfiguracje, których możesz użyć na potrzeby zależności w projekcie Androida.

Konfiguracja Działanie
implementation Gradle dodaje zależność do ścieżki klasy kompilacji i pakuje zależność do danych wyjściowych kompilacji. Gdy moduł konfiguruje zależność implementation, informuje Gradle, że nie chcesz, aby moduł wyciekł zależność do innych modułów podczas kompilacji. Oznacza to, że zależność nie jest dostępna dla innych modułów zależnych od bieżącego modułu.

Użycie tej konfiguracji zależności zamiast api może znacznie skrócić czas kompilacji, ponieważ zmniejsza liczbę modułów, które system kompilacji musi ponownie skompilować. Jeśli na przykład zależność implementation zmieni swój interfejs API, Gradle skompiluje ponownie tylko tę zależność i moduły, które są od niej bezpośrednio zależne. Tej konfiguracji powinna używać większość modułów aplikacji i testowych.

api Gradle dodaje zależność do ścieżki klasy kompilacji i danych wyjściowych kompilacji. Gdy moduł zawiera zależność api, informuje Gradle, że moduł chce tymczasowo wyeksportować tę zależność do innych modułów, aby była dla nich dostępna zarówno w czasie wykonywania, jak i w czasie kompilacji.

Zachowaj tę konfigurację ostrożnie i tylko w przypadku zależności, które musisz eksportować do innych klientów nadrzędnych. Jeśli zależność api zmieni swój zewnętrzny interfejs API, Gradle ponownie skompiluje wszystkie moduły, które mają do niej dostęp podczas kompilacji. Duża liczba zależności api może znacznie wydłużyć czas kompilacji. Jeśli nie chcesz udostępniać interfejsu API zależności dla osobnego modułu, moduły biblioteki powinny zamiast tego używać zależności implementation.

compileOnly Gradle dodaje zależność tylko do ścieżki klasy kompilacji (czyli nie jest dodawana do danych wyjściowych kompilacji). Jest to przydatne, gdy tworzysz moduł Androida i potrzebujesz zależności podczas kompilacji. Trzeba jednak pamiętać, że może być ona obecna w czasie działania. Jeśli na przykład korzystasz z biblioteki, która zawiera tylko adnotacje w czasie kompilacji – są one zwykle używane do generowania kodu, ale często nie są uwzględniane w danych wyjściowych kompilacji – możesz oznaczyć ją jako compileOnly.

Jeśli korzystasz z tej konfiguracji, moduł biblioteki musi zawierać warunek środowiska wykonawczego, aby sprawdzić, czy zależność jest dostępna, a następnie płynnie zmienić jej działanie, tak aby nadal działała, jeśli nie zostanie podana. Pomaga to zmniejszyć rozmiar ostatecznej aplikacji, nie dodając tymczasowych zależności, które nie są kluczowe.

Uwaga: konfiguracji compileOnly nie możesz używać w zależnościach Android Archive (AAR).

runtimeOnly Gradle dodaje zależność tylko do danych wyjściowych kompilacji i będzie ich używać w środowisku wykonawczym. Oznacza to, że nie jest ona dodawana do ścieżki klasy kompilacji. Rzadko jest używana na Androidzie, ale powszechnie używana w aplikacjach serwerowych do implementacji logowania. Na przykład biblioteka może używać interfejsu Logging API, który nie zawiera implementacji. Konsumenci tej biblioteki mogą ją dodać jako zależność implementation i dołączyć zależność runtimeOnly do rzeczywistej implementacji logowania.
ksp
kapt
annotationProcessor

Te konfiguracje dostarczają bibliotekom, które przetwarzają adnotacje i inne symbole w kodzie przed jego skompilowaniem. Zwykle weryfikują one kod lub generują dodatkowy kod, co ogranicza ilość kodu, który musisz napisać.

Aby dodać taką zależność, musisz ją dodać do ścieżki klasy procesora adnotacji za pomocą konfiguracji ksp, kapt lub annotationProcessor. Korzystanie z tych konfiguracji zwiększa wydajność kompilacji przez oddzielenie ścieżki klasy kompilacji od ścieżki klasy procesora adnotacji. Jeśli Gradle znajdzie procesory adnotacji w ścieżce klasy kompilacji, wyłączy unikanie kompilacji, co negatywnie wpłynie na czas kompilacji (Gradle w wersji 5.0 i nowszych ignoruje procesory adnotacji występujące w ścieżce klasy kompilacji).

Wtyczka Androida do obsługi Gradle zakłada, że zależność jest procesorem adnotacji, jeśli jej plik JAR zawiera ten plik:

META-INF/services/javax.annotation.processing.Processor

Jeśli wtyczka wykryje procesor adnotacji, który znajduje się w ścieżce klasy kompilacji, wystąpi błąd kompilacji.

ksp to procesor symboli Kotlin, który jest uruchamiany przez kompilator Kotlin.

kapt i apt to osobne narzędzia, które przetwarzają adnotacje przed wykonaniem kompilatorów Kotlin lub Java.

Wybierając konfigurację, weź pod uwagę te kwestie:

  • Jeśli dostępny jest procesor Kotlin, użyj go jako zależności ksp. Szczegółowe informacje o korzystaniu z procesorów symboli Kotlin znajdziesz w sekcji Migracja z kapt do ksp.
  • Jeśli procesor nie jest dostępny jako procesor symboli Kotlin:
    • Jeśli Twój projekt zawiera źródło Kotlin (ale może też zawierać źródło Java), użyj kapt, aby je uwzględnić.
    • Jeśli Twój projekt korzysta wyłącznie ze źródła w Javie, dołącz go za pomocą właściwości annotationProcessor.

Więcej informacji o korzystaniu z procesorów adnotacji znajdziesz w artykule Dodawanie procesorów adnotacji.

lintChecks

Użyj tej konfiguracji, aby dołączyć bibliotekę zawierającą testy lintowania, które mają być wykonywane przez Gradle podczas tworzenia projektu aplikacji na Androida.

Pamiętaj, że AAR zawierające plik lint.jar automatycznie przeprowadzają testy zdefiniowane w tym pliku lint.jar. Nie musisz dodawać jawnej zależności lintChecks. Dzięki temu możesz definiować biblioteki i powiązane z nimi testy lint w jednej zależności, dzięki czemu testy są wykonywane, gdy klienci korzystają z Twojej biblioteki.

lintPublish Użyj tej konfiguracji w projektach biblioteki Androida, aby uwzględnić testy lintowania, które chcesz skompilować przez Gradle do pliku lint.jar i pakietu w AAR. Powoduje to, że projekty, które zużywają AAR, stosują również te testy lintowania. Jeśli wcześniej korzystano z konfiguracji zależności lintChecks do uwzględniania testów lint w opublikowanym narzędziu AAR, musisz przenieść te zależności, aby zamiast konfiguracji używać konfiguracji lintPublish.

Kotlin

dependencies {
  // Executes lint checks from the ":checks" project at build time.
  lintChecks(project(":checks"))
  // Compiles lint checks from the ":checks-to-publish" into a
  // lint.jar file and publishes it to your Android library.
  lintPublish(project(":checks-to-publish"))
}

Odlotowy

dependencies {
  // Executes lint checks from the ':checks' project at build time.
  lintChecks project(':checks')
  // Compiles lint checks from the ':checks-to-publish' into a
  // lint.jar file and publishes it to your Android library.
  lintPublish project(':checks-to-publish')
}

Konfigurowanie zależności dla określonego wariantu kompilacji

Wszystkie wcześniejsze konfiguracje stosują zależności do wszystkich wariantów kompilacji. Jeśli zamiast tego chcesz zadeklarować zależność tylko dla określonego zestawu źródeł wariantu kompilacji lub dla testowego zbioru źródłowego, musisz zapisać nazwę konfiguracji wielką literą i poprzedzić ją nazwą wariantu kompilacji lub testowego zestawu źródeł.

Aby np. za pomocą konfiguracji implementation dodać zdalną zależność binarną tylko do rodzaju produktu „bezpłatnego”, użyj tego kodu:

Kotlin

dependencies {
    freeImplementation("com.google.firebase:firebase-ads:21.5.1")
}

Odlotowy

dependencies {
    freeImplementation 'com.google.firebase:firebase-ads:21.5.1'
}

Jeśli jednak chcesz dodać zależność do wariantu łączącego rodzaj produktu z typem kompilacji, musisz zainicjować nazwę konfiguracji:

Kotlin

// Initializes a placeholder for the freeDebugImplementation dependency configuration.
val freeDebugImplementation by configurations.creating

dependencies {
    freeDebugImplementation(project(":free-support"))
}

Odlotowy

configurations {
    // Initializes a placeholder for the freeDebugImplementation dependency configuration.
    freeDebugImplementation {}
}

dependencies {
    freeDebugImplementation project(":free-support")
}

Aby dodać zależności implementation dla testów lokalnych i testów instrumentowanych, wygląda to tak:

Kotlin

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

Odlotowy

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

Jednak w takiej sytuacji niektóre konfiguracje nie mają sensu. Na przykład inne moduły nie mogą zależeć od komponentu androidTest, więc jeśli używasz konfiguracji androidTestApi, otrzymasz to ostrzeżenie:

WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with
'androidTestImplementation'.

Kolejność zależności

Kolejność, w jakiej zależności są wymienione, określa priorytet każdej z nich: pierwsza biblioteka ma wyższy priorytet niż druga, druga – itd. Ta kolejność ma znaczenie w przypadku scalania zasobów lub scalania elementów manifestu z aplikacją z bibliotek.

Jeśli na przykład Twój projekt deklaruje:

  • Zależność od LIB_A i LIB_B (w tej kolejności)
  • LIB_A zależy od danych LIB_C i LIB_D (w tej kolejności)
  • LIB_B zależy też od tych danych: LIB_C

W ten sposób ciągła kolejność zależności będzie wyglądać tak:

  1. LIB_A
  2. LIB_D
  3. LIB_B
  4. LIB_C

Dzięki temu zarówno parametr LIB_A, jak i LIB_B mogą zastąpić właściwość LIB_C, a parametr LIB_D nadal ma wyższy priorytet niż element LIB_B, bo parametr LIB_A (zależnie od niego) ma wyższy priorytet niż element LIB_B.

Więcej informacji o scalaniu plików manifestu z różnych źródeł i zależności projektów znajdziesz w artykule Scalanie wielu plików manifestu.

Informacje o zależności w Konsoli Play

Podczas tworzenia aplikacji AGP zawiera metadane opisujące zależności bibliotek, które są skompilowane w aplikację. Podczas przesyłania aplikacji Konsola Play sprawdza te metadane, aby wyświetlić alerty o znanych problemach z pakietami SDK i zależnościami, a w niektórych przypadkach podać przydatne informacje, aby rozwiązać te problemy.

Dane są kompresowane, szyfrowane kluczem podpisywania Google Play i przechowywane w bloku podpisywania wersji aplikacji. Zalecamy przechowywanie tego pliku zależności, aby zapewnić użytkownikom bezpieczeństwo i pozytywne wrażenia. Aby z niej zrezygnować, umieść ten blok dependenciesInfo w pliku build.gradle.kts modułu.

android {
    dependenciesInfo {
        // Disables dependency metadata when building APKs.
        includeInApk = false
        // Disables dependency metadata when building Android App Bundles.
        includeInBundle = false
    }
}

Więcej informacji o naszych zasadach i potencjalnych problemach z zależnościami znajdziesz na stronie pomocy dotyczącej korzystania z pakietów SDK innych firm w aplikacji.

Statystyki pakietów SDK

Android Studio wyświetla ostrzeżenia o lintach w pliku katalogu wersji oraz w oknie projektu dla publicznych pakietów SDK na platformie Google Play SDK Index, jeśli występują te problemy:

  • Autorzy tych pakietów SDK oznaczą je jako nieaktualne.
  • Pakiety SDK naruszają zasady Google Play.

Ostrzeżenia sygnalizują, że należy zaktualizować te zależności, ponieważ używanie nieaktualnych wersji może uniemożliwić publikowanie w Konsoli Google Play w przyszłości.

Dodaj zależności kompilacji bez katalogów wersji

Do dodawania zależności i zarządzania nimi zalecamy używanie katalogów wersji, ale proste projekty mogą ich nie potrzebować. Oto przykład pliku kompilacji, który nie korzysta z katalogów wersji:

Kotlin

plugins {
    id("com.android.application")
}

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation("com.example.android:app-magic:12.3")
    // Dependency on a local library module
    implementation(project(":mylibrary"))
}

Odlotowy

plugins {
    id 'com.android.application'
}

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation 'com.example.android:app-magic:12.3'
    // Dependency on a local library module
    implementation project(':mylibrary')
}

Ten plik kompilacji deklaruje zależność od wersji 12.3 biblioteki „app-magic” w grupie przestrzeni nazw „com.example.android”. Zdalna deklaracja zależności binarnej to:

Kotlin

implementation(group = "com.example.android", name = "app-magic", version = "12.3")

Odlotowy

implementation group: 'com.example.android', name: 'app-magic', version: '12.3'

Plik kompilacji deklaruje też zależność od modułu biblioteki Androida o nazwie „mylibrary”. Ta nazwa musi być zgodna z nazwą biblioteki zdefiniowaną przez include: w pliku settings.gradle.kts. Gdy tworzysz aplikację, system kompilacji kompiluje moduł biblioteki i pakuje wynikową skompilowaną zawartość w aplikacji.

Plik kompilacji deklaruje również zależność od wtyczki Androida do obsługi Gradle (com.application.android). Jeśli masz wiele modułów, które korzystają z tej samej wtyczki, na ścieżce klasy kompilacji możesz mieć tylko jedną wersję wtyczki. Zamiast określać wersję w każdym skrypcie kompilacji modułu, uwzględnij zależność wtyczki w głównym skrypcie kompilacji wraz z jej wersją i wskaż, że nie chcesz jej stosować. Dodanie apply false nakazuje Gradle zanotować wersję wtyczki, ale nie powinna jej używać w kompilacji głównej. Zwykle główny skrypt kompilacji jest pusty z wyjątkiem tego bloku plugins.

Kotlin

plugins {
    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}

Odlotowy

plugins {
    id ‘com.android.application’ version ‘8.3.0-rc02’ apply false
}

Jeśli masz projekt składający się z jednego modułu, możesz określić jego wersję bezpośrednio w skrypcie kompilacji na poziomie modułu, a skrypt kompilacji na poziomie projektu zostaw pusty:

Kotlin

plugins {
    id("com.android.application") version "8.3.0"
}

Odlotowy

plugins {
    id 'com.android.application' version '8.3.0-rc02'
}