Dodaj zależności kompilacji

System kompilacji Gradle w Android Studio umożliwia dodawanie zewnętrznych plików binarnych lub innych modułów biblioteki do kompilacji jako zależności. Zależność może znajdować się na komputerze lub w zdalnym repozytorium. Wszystkie zadeklarowane zależności pośrednie są automatycznie uwzględniane. Na tej stronie opisano, jak używać zależności w projekcie na Androida, w tym szczegóły dotyczące zachowań i konfiguracji specyficznych dla wtyczki Androida do obsługi Gradle (AGP). Pełniejszy przewodnik po zależnościach Gradle znajdziesz w przewodniku po Gradle dotyczącym zarządzania zależnościami. Pamiętaj jednak, że Twój projekt na Androida może korzystać tylko z konfiguracji zależności zdefiniowanych na tej stronie.

Dodawanie biblioteki lub zależności wtyczki

Najlepszym sposobem dodawania zależności kompilacji i zarządzania nimi jest korzystanie z katalogów wersji, czyli metody używanej domyślnie przez nowe projekty. W tej sekcji omawiamy najpopularniejsze typy konfiguracji używanych w projektach na Androida. Więcej opcji znajdziesz w dokumentacji Gradle. Przykład aplikacji, która korzysta z katalogów wersji, znajdziesz w artykule Nowości w Androidzie. Jeśli masz już skonfigurowane zależności kompilacji bez katalogów wersji i projekt wielomodułowy, zalecamy migrację.

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

W tym przykładzie dodajemy do projektu zależność od zdalnej biblioteki binarnej (biblioteka Jetpack Macrobenchmark), zależność od modułu lokalnej biblioteki (myLibrary) oraz zależność od wtyczki (wtyczka Androida do obsługi Gradle). Oto ogólne czynności, które należy wykonać, aby dodać te zależności do projektu:

  1. W sekcji [versions] pliku katalogu wersji dodaj alias wybranej wersji zależności o nazwie libs.versions.toml (w katalogu gradle w widoku Projekt lub Skrypty Gradle 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 lub podkreślenia. Te aliasy generują wartości zagnieżdżone, do których możesz się odwoływać w skryptach kompilacji. Odwołania zaczynają się od nazwy katalogu, czyli części libs w elementach 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 binarnych plików zdalnych lub lokalnych modułów biblioteki) lub [plugins] (w przypadku wtyczek) w 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 publikowanym zestawie materiałów (BOM), który grupuje rodziny bibliotek i ich wersje. Możesz uwzględnić plik BOM w katalogu wersji i plikach kompilacji, aby zarządzał tymi wersjami. Więcej informacji znajdziesz w dokumentacji dotyczącej specyfikacji materiałowej.

  3. Dodaj odwołanie do aliasu zależności do skryptu kompilacji modułów, które wymagają tej zależności. Podczas odwoływania się do aliasu w skrypcie kompilacji należy zastąpić jego podkreślenia i kreski kropkami. Nasz skrypt kompilacji na poziomie modułu będzie wyglądał tak:

    Kotlin

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

    Groovy

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

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

Konfigurowanie zależności

W bloku dependencies możesz zadeklarować zależność od biblioteki, korzystając z jednego z kilku różnych konfiguracji zależności (np. implementation pokazanej wcześniej). Każda konfiguracja zależności dostarcza Gradle różne instrukcje dotyczące korzystania z tej zależności. W tabeli poniżej opisujemy poszczególne konfiguracje, których możesz używać w przypadku zależności w projekcie na Androida.

Konfiguracja Działanie
implementation Gradle dodaje zależność do ścieżki kompilacji i pakuje ją do danych wyjściowych kompilacji. Gdy moduł konfiguruje zależność implementation, informuje Gradle, że nie chcesz, aby moduł przekazywał tę zależność do innych modułów w czasie kompilacji. Oznacza to, że zależność nie jest udostępniana innym modułom, które są zależne od bieżącego modułu.

Korzystanie z 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 interfejs API, Gradle skompiluje tylko tę zależność i moduły, które bezpośrednio od niej zależą. W przypadku większości aplikacji i modułów testowych należy użyć tej konfiguracji.

api Gradle dodaje zależność do ścieżki kompilacji i wyjścia kompilacji. Jeśli moduł zawiera zależność api, informuje Gradle, że chce eksportować tę zależność do innych modułów, aby była ona dla nich dostępna zarówno w czasie wykonywania, jak i kompilacji.

Używaj tej konfiguracji ostrożnie i tylko w przypadku zależności, które musisz eksportować do innych konsumentów w górę łańcucha. Jeśli zależność api zmieni swój zewnętrzny interfejs API, Gradle ponownie skompiluje wszystkie moduły, które mają dostęp do tej zależności w momencie 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 osobnemu modułowi, moduły bibliotek powinny używać zależności implementation.

compileOnly Gradle dodaje zależność tylko do ścieżki kompilacji (czyli nie jest ona dodawana do danych wyjściowych kompilacji). Jest to przydatne, gdy tworzysz moduł Androida i potrzebujesz zależności podczas kompilacji, ale nie musisz jej mieć w czasie wykonywania. Jeśli na przykład zależy Ci na bibliotece, która zawiera tylko adnotacje kompilacyjne (zazwyczaj używane do generowania kodu, ale często nieuwzględnione w wyniku kompilacji), możesz ją oznaczyć jako compileOnly.

Jeśli używasz tej konfiguracji, moduł biblioteki musi zawierać warunek czasu wykonywania, aby sprawdzić, czy zależność jest dostępna, a następnie łagodnie zmienić swoje działanie, aby nadal działał, jeśli zależność nie jest dostępna. Pomaga to zmniejszyć rozmiar końcowej aplikacji, ponieważ nie dodaje tymczasowych zależności, które nie są kluczowe.

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

runtimeOnly Gradle dodaje zależność tylko do danych wyjściowych kompilacji, aby można było jej używać w czasie wykonywania. Oznacza to, że nie jest ona dodawana do ścieżki kompilacji. Ta metoda jest rzadko używana na Androidzie, ale często jest stosowana w aplikacji serwera do implementacji rejestrowania. Na przykład biblioteka może używać interfejsu API do rejestrowania, który nie zawiera implementacji. Użytkownicy tej biblioteki mogą dodać ją jako zależność implementation i uwzględnić zależność runtimeOnly dla rzeczywistej implementacji logowania, której mają używać.
ksp
kapt
annotationProcessor

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

Aby dodać taką zależność, musisz ją dodać do ścieżki klas procesora adnotacji za pomocą konfiguracji ksp, kapt lub annotationProcessor. Korzystanie z tych konfiguracji poprawia wydajność kompilacji przez rozdzielenie ścieżki klas kompilacji od ścieżki klas procesora adnotacji. Jeśli Gradle znajdzie procesory adnotacji w ścieżce kompilacji, dezaktywuje unikanie kompilacji, co negatywnie wpływa na czas kompilacji (Gradle w wersji 5.0 i nowszej ignoruje procesory adnotacji znalezione w ścieżce kompilacji).

Jeśli plik JAR zawiera ten plik:

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

Jeśli wtyczka wykryje procesor adnotacji, który znajduje się na classpath kompilacji, wygeneruje błąd kompilacji.

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

kaptapt 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 Kotlina, użyj go jako zależności ksp. Szczegółowe informacje o używaniu procesorów symboli Kotlina znajdziesz w artykule Migracja z kapt na ksp.
  • Jeśli procesor nie jest dostępny jako procesor symboli Kotlin:
    • Jeśli Twój projekt zawiera kod źródłowy Kotlin (ale może też zawierać kod źródłowy Java), użyj kapt, aby go uwzględnić.
    • Jeśli Twój projekt korzysta tylko z źródła kodu w języku Java, użyj annotationProcessor, aby go uwzględnić.

Więcej informacji o używaniu procesorów adnotacji znajdziesz w artykule Dodawanie procesorów adnotacji.

lintChecks

Użyj tej konfiguracji, aby uwzględnić bibliotekę zawierającą kontrole lint, które mają być wykonywane przez Gradle podczas kompilowania projektu aplikacji na Androida.

Pamiętaj, że pliki AAR zawierające plik lint.jar automatycznie przeprowadzają kontrole zdefiniowane w tym pliku. Nie musisz dodawać jawnej zależności lintChecks.lint.jar Dzięki temu możesz definiować biblioteki i powiązane z nimi kontrole lint w ramach pojedynczej zależności, co zapewnia uruchamianie kontroli, gdy użytkownicy korzystają z Twojej biblioteki.

lintPublish Użyj tej konfiguracji w projektach bibliotek na Androida, aby uwzględnić kontrole lint, które chcesz skompilować w pliku lint.jar i zapakować w pliku AAR. W efekcie projekty, które korzystają z Twojego pliku AAR, również stosują te kontrole lint. Jeśli wcześniej używałeś/używałaś konfiguracji zależności lintChecks, aby uwzględnić w opublikowanym pliku AAR sprawdzanie lint, musisz przenieść te zależności, aby zamiast tego 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"))
}

Groovy

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 konkretnego wariantu kompilacji

Wszystkie powyższe konfiguracje stosują zależności do wszystkich wariantów kompilacji. Jeśli chcesz zadeklarować zależność tylko w przypadku konkretnego zestawu źródeł wariantu kompilacji lub testów, musisz użyć nazwy konfiguracji z dużych liter i dodać do niej nazwę wariantu kompilacji lub zestawu źródeł testów.

Aby na przykład dodać zdalne binarne zależności tylko do wersji „free” produktu za pomocą konfiguracji implementation, użyj tego kodu:

Kotlin

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

Groovy

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

Jeśli jednak chcesz dodać zależność dla wariantu, który łączy wersję produktu i typ kompilacji, musisz zainicjować nazwę konfiguracji:

Kotlin

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

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

Groovy

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

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

Dodawanie zależności implementation do testów lokalnych i testów z instrumentacją:

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.6.1")
}

Groovy

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.6.1'
}

W tej sytuacji niektóre konfiguracje nie mają jednak sensu. Na przykład inne moduły nie mogą zależeć od androidTest, więc jeśli używasz konfiguracji androidTestApi, wyświetla się to ostrzeżenie:

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

Kolejność zależności

Kolejność, w jakiej wymieniasz zależności, wskazuje ich priorytet: pierwsza biblioteka ma wyższy priorytet niż druga, druga wyższy niż trzecia itd. Ta kolejność jest ważna w przypadku łączenia zasobów lub łączenia elementów manifestu z bibliotek do aplikacji.

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

  • Zależność od LIB_ALIB_B (w tej kolejności)
  • LIB_A zależy od LIB_CLIB_D (w tej kolejności).
  • Funkcja LIB_B zależy też od LIB_C

Wtedy kolejność zależności płaskich 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 nadal ma wyższy priorytet niż LIB_B, ponieważ LIB_A (od którego zależy) ma wyższy priorytet niż LIB_B.

Więcej informacji o tym, jak scalać manifesty z różnych źródeł/zależności projektu, znajdziesz w artykule Scalanie wielu plików manifestu.

Informacje o zależnościach w Konsoli Play

Podczas kompilowania aplikacji AGP zawiera metadane opisujące zależności bibliotek, które są kompilowane w aplikacji. Podczas przesyłania aplikacji Konsola Play sprawdza te metadane, aby wyświetlać alerty o znanych problemach z pakietami SDK i zależnościami, których używa aplikacja. W niektórych przypadkach może też wyświetlać informacje, które pomogą Ci rozwiązać te problemy.

Dane są kompresowane, szyfrowane za pomocą klucza podpisywania Google Play i przechowywane w bloku podpisywania aplikacji. Zalecamy zachowanie tego pliku zależności, aby zapewnić użytkownikom bezpieczne i pozytywne wrażenia. Możesz zrezygnować z tego sposobu, dodając ten blok kodu 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 poświęconej korzystaniu w aplikacji z pakietów SDK innych firm.

Statystyki pakietu SDK

W Android Studio w pliku katalogu wersji i w oknie dialogowym Struktura projektu dla publicznych pakietów SDK na platformie Google Play SDK Index wyświetlane są ostrzeżenia lint w przypadku tych problemów:

  • Pakiety SDK są oznaczone przez ich autorów jako przestarzałe.
  • Pakiety SDK naruszają zasady Google Play.

Ostrzeżenia są sygnałem, że należy zaktualizować te zależności, ponieważ korzystanie z nieaktualnych wersji może uniemożliwić opublikowanie aplikacji w Konsoli Google Play w przyszłości.

Dodawanie 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ą ich nie wymagać. Oto przykład pliku kompilacji, który nie używa 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"))
}

Groovy

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”. Deklaracja zależności binarnych z dalszego serwera to skrót od:

Kotlin

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

Groovy

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”. Nazwa ta musi być zgodna z nazwą biblioteki zdefiniowaną za pomocą include: w pliku settings.gradle.kts. Podczas kompilowania aplikacji system kompilacji kompiluje moduł biblioteki i przechowuje wynikową skompilowaną zawartość w aplikacji.

Plik build.gradle deklaruje też zależność od wtyczki Gradle dla Androida (com.application.android). Jeśli masz kilka modułów, które korzystają z tego samego wtyczka, w ścieżce klas build.gradle może być tylko jedna wersja wtyczki. Zamiast określać wersję w każdym pliku skryptu kompilacji modułu, należy uwzględnić zależność wtyczki w pliku skryptu kompilacji głównego z wersją i wskazywać, aby jej nie stosować. Dodanie apply false powoduje, że Gradle zapisuje wersję wtyczki, ale nie używa jej w kompilacji głównej. Zwykle skrypt kompilacji główny jest pusty, z wyjątkiem bloku plugins.

Kotlin

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

Groovy

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

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

Kotlin

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

Groovy

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