Dodaj zależności kompilacji

System kompilacji Gradle w Android Studio umożliwia dołączenie do kompilacji zewnętrznych plików binarnych lub innych modułów biblioteki jako zależności. Zależności mogą znajdować się na maszynie lub w zdalnym repozytorium, a wszelkie zadeklarowane przez nie zależności przechodnie również są uwzględniane automatycznie. Na tej stronie opisujemy, jak korzystać z zależności w projekcie Androida, w tym szczegóły dotyczące zachowań i konfiguracji specyficznych dla wtyczki Androida do obsługi Gradle (AGP). Bardziej ogólny przewodnik po zależnościach Gradle znajdziesz też w przewodniku Gradle do zarządzania zależnościami – pamiętaj jednak, że Twój projekt na Androida może używać tylko konfiguracji zależności zdefiniowanych na tej stronie.

Dodaj zależność biblioteki lub wtyczki

Najlepszym sposobem na dodawanie zależności kompilacji i zarządzanie nimi jest używanie katalogów wersji, czyli metody, z której domyślnie korzystają nowe projekty. W tej sekcji znajdziesz najczęstsze typy konfiguracji używane w projektach na Androida. Więcej opcji znajdziesz w dokumentacji Gradle. Przykład aplikacji, która korzysta z katalogów wersji, znajdziesz w sekcji Teraz na Androidzie. Jeśli masz już skonfigurowane zależności kompilacji bez katalogów wersji i masz projekt z wieloma modułami, zalecamy migrację.

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

W poniższym przykładzie dodajemy do naszego projektu zależność zdalnego pliku binarnego (biblioteka Jetpack Macrobenchmark), zależność modułu biblioteki lokalnej (myLibrary) oraz zależność wtyczki (wtyczka Androida do obsługi Gradle). Oto ogólne czynności, które musisz wykonać, aby dodać te zależności do projektu:

  1. Dodaj alias wersji zależności, której chcesz używać, w sekcji [versions] pliku katalogu wersji o nazwie libs.versions.toml (w katalogu gradle w widoku Projekt lub Gradle Scripts w widoku Android):

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

    Aliasy mogą zawierać myślniki i 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 używasz katalogu z jedną wersją, zalecamy zachowanie domyślnej wartości „libs”.

  2. Dodaj alias zależności w sekcji [libraries] (w przypadku zdalnych plików binarnych lub modułów lokalnych bibliotek) 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 liście materiałów (BOM), która grupuje rodziny bibliotek i ich wersje. Możesz umieścić BOM w katalogu wersji i plikach kompilacji, a następnie zarządzać tymi wersjami za Ciebie. Więcej informacji znajdziesz w artykule Korzystanie z zestawu materiałów.

  3. Dodaj odwołanie do aliasu zależności do skryptu kompilacji modułów, które wymagają zależności. Zamień podkreślenia i myślniki aliasu na kropki, gdy odwołasz 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)
    }
    

    Odlotowe

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

    Odniesienia do wtyczek zawierają kod plugins po nazwie katalogu, a odwołania do wersji zawierają po nazwie katalogu ciąg versions (odwołania do wersji są rzadkością – przykłady odwołań do wersji znajdziesz w sekcji Zależności z takimi samymi numerami wersji). Odwołania do biblioteki nie zawierają kwalifikatora libraries, więc nie możesz użyć właściwości 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 przekazuje Gradle różne instrukcje użycia tej zależności. W tabeli poniżej opisano wszystkie konfiguracje, których możesz użyć jako 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ł ujawnił zależność innym modułom podczas kompilowania. Oznacza to, że zależność ta nie jest dostępna dla innych modułów zależnych od bieżącego.

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 zmienia swój interfejs API, Gradle ponownie skompiluje tylko tę zależność i moduły, które są od niej bezpośrednio zależne. Większość modułów aplikacji i testów powinna używać tej konfiguracji.

api Gradle dodaje zależność do ścieżki klasy kompilacji i danych wyjściowych kompilacji. Gdy moduł zawiera zależność api, informuje on Gradle, że chce on przenieść zależność do innych modułów, aby była ona dostępna zarówno w czasie działania, jak i podczas kompilacji.

Korzystaj z tej konfiguracji ostrożnie i uwzględnij tylko zależności, które musisz okresowo eksportować do innych użytkowników nadrzędnych. Jeśli zależność api zmienia swój zewnętrzny interfejs API, podczas kompilowania Gradle ponownie skompiluje wszystkie moduły, które mają do niej dostęp. Duża liczba zależności api może znacznie wydłużyć czas kompilacji. Jeśli nie chcesz udostępnić interfejsu API zależności w osobnym module, moduły biblioteki powinny 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. Możesz też umieścić go w czasie działania. Jeśli na przykład korzystasz z biblioteki, która zawiera tylko adnotacje podczas kompilacji (zwykle jest ona używana do generowania kodu, ale często nie jest uwzględniana w danych wyjściowych kompilacji), możesz oznaczyć ją jako compileOnly.

Jeśli używasz tej konfiguracji, moduł biblioteki musi zawierać warunek środowiska wykonawczego, który pozwala sprawdzić, czy zależność jest dostępna, a następnie płynnie zmienić jego działanie, aby nadal działał, jeśli nie zostanie podany. Pomaga to zmniejszyć rozmiar ostatecznej aplikacji dzięki unikaniu dodawania tymczasowych zależności, które nie są kluczowe.

Uwaga: konfiguracji compileOnly nie można używać z zależnościami archiwum Android (AAR).

runtimeOnly Gradle dodaje zależność tylko do danych wyjściowych kompilacji, która jest używana w czasie działania. Oznacza to, że nie jest on dodawany do ścieżki klasy kompilacji. Rzadko jest używana na Androidzie, ale powszechnie używa się w aplikacjach serwerowych do implementacji logowania. Na przykład biblioteka może używać interfejsu API logowania, który nie obejmuje implementacji. Konsumenci tej biblioteki mogą dodać ją jako zależność implementation i uwzględnić zależność runtimeOnly, która będzie używana w rzeczywistej implementacji logowania.
ksp
kapt
annotationProcessor

Te konfiguracje udostępniają biblioteki, które przetwarzają adnotacje i inne symbole w kodzie przed jego skompilowaniem. Zazwyczaj weryfikują one kod lub generują dodatkowy kod, co ogranicza potrzebny do napisania kod.

Aby dodać taką zależność, musisz dodać ją do ścieżki klasy procesora adnotacji przy użyciu konfiguracji ksp, kapt lub annotationProcessor. Użycie 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, dezaktywuje funkcję unikania kompilacji, co negatywnie wpływa na czas kompilacji (Gradle w wersji 5.0 lub nowszej ignoruje procesory adnotacji znajdujące się w ścieżce klasy kompilacji).

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

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

Jeśli wtyczka wykryje procesor adnotacji znajdujący się w ścieżce klasy kompilacji, wywoła błąd kompilacji.

ksp to procesor symboli Kotlin 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 procesor jest dostępny jako procesor symboli Kotlin, użyj go jako zależności ksp. Szczegółowe informacje o używaniu procesorów symboli Kotlin znajdziesz w artykule 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 w Javie), użyj kapt, aby je uwzględnić.
    • Jeśli w Twoim projekcie używane jest tylko źródło w Javie, dodaj je za pomocą annotationProcessor.

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

lintChecks

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

Pamiętaj, że AAR zawierające plik lint.jar automatycznie uruchamiają kontrole zdefiniowane w tym pliku lint.jar. Nie musisz dodawać wyraźnej zależności lintChecks. Dzięki temu możesz zdefiniować biblioteki i powiązane kontrole lintowania w jednej zależności, dzięki czemu masz pewność, że testy są wykonywane, gdy konsumenci korzystają z Twojej biblioteki.

lintPublish Użyj tej konfiguracji w projektach bibliotek Androida, aby uwzględnić testy lintowania, które Gradle ma skompilować w plik lint.jar i pakiet w AAR. Dzięki temu projekty, które wykorzystują Twoje AAR, stosują też kontrolę lintowania. Jeśli wcześniej konfiguracja zależności lintChecks uwzględniała kontrole lint w opublikowanym AAR, musisz przenieść te zależności, aby korzystały z 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"))
}

Odlotowe

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 poprzednie konfiguracje stosują zależności do wszystkich wariantów kompilacji. Jeśli zamiast tego chcesz zadeklarować zależność tylko dla określonego zbioru źródłowego wersji kompilacji lub dla testowego zbioru źródłowego, musisz napisać nazwę konfiguracji wielką literą i poprzedzić ją nazwą wariantu kompilacji lub zbioru źródłowego testowego.

Aby na przykład dodać zdalną zależność binarną tylko do „bezpłatnego” rodzaju produktów za pomocą konfiguracji implementation, użyj tego polecenia:

Kotlin

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

Odlotowe

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

Jeśli jednak chcesz dodać zależność do wersji, która łączy 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"))
}

Odlotowe

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

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

Aby dodać zależności implementation na potrzeby 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")
}

Odlotowe

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 androidTest, dlatego jeśli użyjesz konfiguracji androidTestApi, wyświetli się to ostrzeżenie:

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

Kolejność zależności

Kolejność wyświetlania zależności wskazuje na ich priorytet: pierwsza biblioteka ma wyższy priorytet niż druga, druga itd. Ta kolejność ma znaczenie, jeśli zasoby zostały scalone lub elementy manifestu zostały scalone w aplikacji z bibliotek.

Jeśli na przykład projekt deklaruje te elementy:

  • Zależność od LIB_A i LIB_B (w tej kolejności)
  • LIB_A zależy od wartości LIB_C i LIB_D (w tej kolejności)
  • LIB_B zależy również od: LIB_C

W takiej sytuacji kolejność zależności stałych będzie wyglądać tak:

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

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

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

Informacje o zależności w Konsoli Play

Podczas tworzenia aplikacji architektura AGP zawiera metadane opisujące zależności dotyczące bibliotek. Podczas przesyłania aplikacji Konsola Play sprawdza te metadane, aby wyświetlić alerty o znanych problemach z pakietami SDK i zależnościami, z których korzysta, a w niektórych przypadkach przekazać przydatne informacje zwrotne w celu rozwiązania tych problemów.

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

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 naszej stronie pomocy dotyczącej korzystania w aplikacji z pakietów SDK innych firm.

Statystyki dotyczące pakietu SDK

Android Studio wyświetla ostrzeżenia o linkach w pliku katalogu wersji i w Project Aspect Dialog w przypadku publicznych pakietów SDK na platformie Google Play SDK Index, jeśli występują te problemy:

  • Pakiety SDK zostały oznaczone przez autorów jako nieaktualne.
  • Naruszają zasady Google Play.

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

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

Zalecamy korzystanie z katalogów wersji do dodawania zależności i zarządzania nimi, ale proste projekty mogą nie być potrzebne. 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"))
}

Odlotowe

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 plików binarnych to skrócony skrót:

Kotlin

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

Odlotowe

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

Plik kompilacji deklaruje również zależność od modułu biblioteki Androida o nazwie „mylibrary”. Ta nazwa musi być zgodna z nazwą biblioteki zdefiniowaną za pomocą include: w pliku settings.gradle.kts. Podczas tworzenia aplikacji system kompilacji kompiluje moduł biblioteki i umieszcza w aplikacji powstałą w ten sposób skompilowaną zawartość.

Plik kompilacji deklaruje również zależność od wtyczki Androida do obsługi Gradle (com.application.android). Jeśli masz kilka modułów korzystających z tej samej wtyczki, w ścieżce klasy kompilacji dla wszystkich modułów możesz mieć tylko jedną wersję wtyczki. Zamiast określać wersję w każdym ze skryptów kompilacji modułu, uwzględnij zależność wtyczki w głównym skrypcie kompilacji i wskaż wersję, by jej nie stosować. Dodanie parametru apply false informuje Gradle, aby zanotował wersję wtyczki, ale nie ma 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
}

Odlotowe

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

Jeśli masz projekt z jednym modułem, możesz wyraźnie określić wersję w skrypcie kompilacji na poziomie modułu i pozostawić skrypt kompilacji na poziomie projektu pusty:

Kotlin

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

Odlotowe

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