Dodawanie zależności kompilacji

System kompilacji Gradle w Android Studio umożliwia dołączanie do kompilacji zewnętrznych plików binarnych lub innych modułów biblioteki jako zależności. Zależności mogą znajdować się na Twoim komputerze lub w zdalnym repozytorium, a wszystkie zadeklarowane przez nie zależności przechodnie są automatycznie uwzględniane. Na tej stronie opisujemy, jak używać zależności w projekcie na Androida. Znajdziesz tu też szczegółowe informacje o zachowaniach i konfiguracjach, które są specyficzne dla wtyczki Androida do obsługi Gradle (AGP). Szczegółowe informacje o zależnościach Gradle znajdziesz w przewodniku Gradle dotyczącym zarządzania zależnościami. Pamiętaj jednak, że Twój projekt na Androida musi używać tylko konfiguracji zależności zdefiniowanych na tej stronie.

Dodawanie zależności biblioteki lub wtyczki

Najlepszym sposobem na dodawanie zależności kompilacji i zarządzanie nimi jest używanie katalogów wersji. Jest to metoda, z której domyślnie korzystają nowe projekty. W tej sekcji opisujemy 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 Now in Android. 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 (nie są powszechne) i zarządzania nimi znajdziesz w sekcji Zależności natywne.

W tym przykładzie dodajemy do projektu zależność od zdalnego pliku binarnego (bibliotekę Jetpack Macrobenchmark), zależność od lokalnego modułu biblioteki (myLibrary) i zależność od wtyczki (wtyczki Androida do obsługi Gradle). Oto ogólne kroki dodawania tych 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 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 i podkreślenia. Te aliasy 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 libs części libs.versions.toml. Jeśli używasz katalogu z jedną wersją, zalecamy pozostawienie domyślnej wartości „libs”.

  2. Dodaj alias zależności w sekcji [libraries] (w przypadku zdalnych plików binarnych 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 opublikowanym wykazie materiałów (BOM), który grupuje rodziny bibliotek i ich wersje. Możesz uwzględnić BOM w katalogu wersji i plikach kompilacji, a następnie pozwolić mu zarządzać tymi wersjami. Więcej informacji znajdziesz w artykule Korzystanie z zestawienia materiałów.

  3. Dodaj odwołanie do aliasu zależności w skrypcie kompilacji modułów, które wymagają tej zależności. Podczas odwoływania się do aliasu w skrypcie kompilacji zamień podkreślenia i myślniki na kropki. 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)
    }

    Groovy

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

    Odwołania do wtyczek zawierają znak plugins po nazwie katalogu, a odwołania do wersji zawierają znak versions po nazwie katalogu (odwołania do wersji są rzadkie; przykłady odwołań do wersji 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żywać znaków versions ani plugins na początku aliasu biblioteki.

Konfigurowanie zależności

W bloku dependencies możesz zadeklarować zależność biblioteki, używając jednej z kilku różnych konfiguracji zależności (np. implementation pokazanej wcześniej). Każda konfiguracja zależności zawiera inne instrukcje dla Gradle dotyczące sposobu korzystania z zależności. W tabeli poniżej opisujemy każdą z konfiguracji, których możesz użyć w przypadku zależności w projekcie na Androida.

Konfiguracja Działanie
implementation Gradle dodaje zależność do ścieżki klas kompilacji i pakuje ją do danych wyjściowych kompilacji. Gdy moduł konfiguruje implementationzależność, informuje Gradle, że nie chcesz, aby moduł ujawniał zależność innym modułom w czasie kompilacji. Oznacza to, że zależność nie jest udostępniana innym modułom, które zależą 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 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 korzystać z tej konfiguracji.

api Gradle dodaje zależność do ścieżki kompilacji i danych wyjściowych kompilacji. Gdy moduł zawiera zależność api, oznacza to, że informuje Gradle, że chce przechodnio eksportować tę zależność do innych modułów, aby była dostępna w czasie wykonywania i kompilacji.

Używaj tej konfiguracji ostrożnie i tylko w przypadku zależności, które musisz eksportować przechodnio do innych odbiorców wyższego poziomu. Jeśli api zmieni swój zewnętrzny interfejs API, Gradle ponownie skompiluje w czasie kompilacji wszystkie moduły, które mają dostęp do tej zależności. Duża liczba api zależności może znacznie wydłużyć czas kompilacji. Jeśli nie chcesz udostępniać interfejsu API zależności w osobnym module, moduły biblioteki powinny zamiast tego używać zależności implementation.

compileOnly Gradle dodaje zależność tylko do ścieżki klas 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 jest ona wymagana w czasie działania. Jeśli na przykład korzystasz z biblioteki, która zawiera tylko adnotacje w czasie kompilacji (zwykle używane do generowania kodu, ale często nie są uwzględniane w danych wyjściowych kompilacji), możesz oznaczyć tę bibliotekę jako compileOnly.

Jeśli używasz tej konfiguracji, moduł biblioteki musi zawierać warunek czasu działania, który sprawdza, czy zależność jest dostępna, a następnie płynnie zmienia swoje działanie, aby nadal funkcjonować, jeśli nie jest dostępna. Pomaga to zmniejszyć rozmiar końcowej aplikacji, ponieważ nie dodaje przejściowych zależności, które nie są krytyczne.

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

runtimeOnly Gradle dodaje zależność tylko do danych wyjściowych kompilacji, aby można było jej używać w czasie działania. Oznacza to, że nie jest dodawana do ścieżki klas kompilacji. Jest to rzadko używane na Androidzie, ale często w aplikacjach serwerowych do udostępniania 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 w przypadku rzeczywistej implementacji rejestrowania, której chcą używać.
ksp
kapt
annotationProcessor

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

Aby dodać taką zależność, musisz dodać ją do ścieżki klasy procesora adnotacji, używając konfiguracji ksp, kapt lub annotationProcessor. Korzystanie z tych konfiguracji zwiększa wydajność kompilacji, ponieważ oddziela ścieżkę klas kompilacji od ścieżki klas procesora adnotacji. Jeśli Gradle znajdzie procesory adnotacji na ścieżce klas kompilacji, dezaktywuje unikanie kompilacji, co negatywnie wpływa na czas kompilacji (Gradle w wersji 5.0 i nowszej ignoruje procesory adnotacji znalezione na ścieżce klas kompilacji).

Wtyczka Androida do obsługi Gradle zakłada, że zależność jest procesorem adnotacji, 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 ścieżce klas kompilacji, spowoduje to błąd kompilacji.

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

kaptapt to osobne narzędzia, które przetwarzają adnotacje przed uruchomieniem 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. Więcej informacji o korzystaniu z procesorów symboli Kotlin znajdziesz w artykule Migracja z kapt na ksp.
  • Jeśli procesor nie jest dostępny jako procesor symboli Kotlin:
    • Jeśli projekt zawiera źródło Kotlin (ale może też zawierać źródło Java), użyj kapt, aby je uwzględnić.
    • Jeśli projekt korzysta tylko ze źródeł Java, użyj annotationProcessor, aby je 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ą testy lint, które Gradle ma wykonywać podczas tworzenia projektu aplikacji na Androida.

Pamiętaj, że biblioteki 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 zdefiniować biblioteki i powiązane z nimi testy Lint w ramach jednej zależności, co zapewni uruchamianie testów, gdy użytkownicy będą korzystać z Twojej biblioteki.

lintPublish Użyj tej konfiguracji w projektach bibliotek Androida, aby uwzględnić testy lint, które Gradle ma skompilować do pliku lint.jar i spakować w AAR. Spowoduje to, że projekty korzystające z Twojego pliku AAR również będą stosować te testy lint. Jeśli wcześniej używasz konfiguracji zależności lintChecks, aby uwzględnić w opublikowanym pliku AAR sprawdzanie za pomocą narzędzia 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 dla określonego zestawu źródeł wersji kompilacji lub zestawu źródeł testowych, musisz napisać nazwę konfiguracji wielkimi literami i dodać przed nią nazwę wersji kompilacji lub zestawu źródeł testowych.

Jeśli na przykład chcesz dodać zdalną zależność binarną tylko do wersji produktu „free” 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")
}

Aby dodać zależności implementation do testów lokalnych i testów z instrumentacją, zrób to w ten sposób:

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

Jednak w tej sytuacji niektóre konfiguracje nie mają sensu. Na przykład inne moduły nie mogą zależeć od androidTest, więc jeśli użyjesz konfiguracji androidTestApi, pojawi się ten komunikat ostrzegawczy:

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

Kolejność zależności

Kolejność, w jakiej wymieniasz zależności, wskazuje priorytet każdej z nich: pierwsza biblioteka ma wyższy priorytet niż druga, druga ma wyższy priorytet niż trzecia itd. Ta kolejność jest ważna w przypadku scalania zasobów lub scalania elementów manifestu z bibliotek w 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).
  • LIB_B zależy też od LIB_C

Wtedy 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 LIB_A, jak i LIB_B mogą zastąpić LIB_C, a LIB_D ma wyższy priorytet niż LIB_B, ponieważ LIB_A (który od niego zależy) ma wyższy priorytet niż LIB_B.

Więcej informacji o tym, jak scalane są pliki manifestu 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 tworzenia aplikacji wtyczka AGP uwzględnia metadane opisujące zależności bibliotek skompilowane 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 używanymi przez aplikację, a w niektórych przypadkach przekazywać przydatne informacje, które pomogą rozwiązać te problemy.

Dane są kompresowane, szyfrowane za pomocą klucza podpisywania Google Play i przechowywane w bloku podpisywania aplikacji w wersji produkcyjnej. Zalecamy zachowanie tego pliku zależności, aby zapewnić użytkownikom bezpieczeństwo i pozytywne wrażenia. Możesz zrezygnować, dodając ten blok dependenciesInfo do 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 w aplikacji z pakietów SDK innych firm.

Statystyki dotyczące pakietu SDK

Android Studio wyświetla ostrzeżenia narzędzia lint w pliku katalogu wersji i w oknie struktury projektu w przypadku publicznych pakietów SDK na platformie Google Play SDK Index, gdy występują te problemy:

  • Pakiety SDK są oznaczane jako nieaktualne przez ich autorów.
  • Pakiety SDK naruszają zasady Google Play.
  • Pakiety SDK mają znane luki w zabezpieczeniach.
  • Pakiety SDK zostały wycofane przez ich autorów.

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

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

Do dodawania zależności i zarządzania nimi zalecamy używanie katalogów wersji, ale w przypadku prostych projektów może to nie być konieczne. 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"))
}

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 zdalnej zależności binarnej jest skrótem następującej deklaracji:

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

Plik kompilacji deklaruje też zależność od wtyczki Android Gradle (com.application.android). Jeśli masz wiele modułów, które używają tej samej wtyczki, w ścieżce klasy kompilacji wszystkich modułów może być tylko jedna wersja wtyczki. Zamiast określać wersję w każdym skrypcie kompilacji modułu, w głównym skrypcie kompilacji uwzględnij zależność wtyczki z wersją i wskaż, aby jej nie stosować. Dodanie apply false informuje Gradle, że ma zapisać wersję wtyczki, ale nie używać jej 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
}

Groovy

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

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

Kotlin

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

Groovy

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