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 bibliotek jako zależności. Zależności mogą znajdować się na Twoim komputerze lub w zdalnym repozytorium. Wszystkie zadeklarowane przez nie zależności przechodnie są również automatycznie uwzględniane. Na tej stronie opisujemy, jak używać zależności w projekcie aplikacji na Androida, w tym szczegóły dotyczące zachowań i konfiguracji, które są specyficzne dla wtyczki Androida do obsługi Gradle (AGP). Bardziej szczegółowe informacje o zależnościach Gradle znajdziesz w przewodniku po zarządzaniu zależnościami w Gradle. Pamiętaj jednak, że Twój projekt aplikacji na Androida musi używać tylko konfiguracji zależności zdefiniowanych na tej stronie.

Dodawanie zależności biblioteki lub wtyczki

Najlepszym sposobem dodawania zależności kompilacji i zarządzania nimi jest używanie katalogów wersji, czyli metody, którą domyślnie stosują nowe projekty. W tej sekcji znajdziesz najczęstsze typy konfiguracji używane w projektach aplikacji na Androida. Więcej opcji znajdziesz w dokumentacji Gradle. Przykład aplikacji, która używa katalogów wersji, znajdziesz w Now in Android. Jeśli masz już skonfigurowane zależności kompilacji bez katalogów wersji i masz projekt wielomodułowy, zalecamy migrację.

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

W poniższym przykładzie do projektu dodano zdalną zależność binarną (bibliotekę Jetpack Macrobenchmark), zależność lokalnego modułu biblioteki (myLibrary) i zależność wtyczki (wtyczka Androida do obsługi Gradle). Oto ogólne instrukcje dodawania tych zależności do projektu:

  1. Dodaj alias wersji zależności, której chcesz użyć, 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ć łączniki i podkreślenia. Te aliasy generują zagnieżdżone wartości, do których można się odwoływać w skryptach kompilacji. Odwołania zaczynają się od nazwy katalogu, czyli części libs w 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) 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 komponentów (BOM), które grupuje rodziny bibliotek i ich wersje. Możesz uwzględnić BOM w katalogu wersji i plikach kompilacji, aby 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. Podczas odwoływania się do aliasu ze skryptu kompilacji zamień podkreślenia i myślniki na kropki. 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)
    }

    Dynamiczny

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

    Odwołania do wtyczek zawierają plugins po nazwie katalogu, a odwołania do wersji zawierają 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ć 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 dostarcza Gradle różne instrukcje dotyczące korzystania z zależności. W tabeli poniżej opisujemy każdą konfigurację, której możesz użyć w przypadku zależności w projekcie aplikacji na Androida.

Konfiguracja Zachowanie
implementation Gradle dodaje zależność do ścieżki klasy kompilacji i pakuje ją do danych wyjściowych kompilacji. Gdy moduł konfiguruje zależność implementation, 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 bezpośrednio od niej zależą. 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 Gradle, że chce przejściowo wyeksportować tę zależność do innych modułów, aby była dla nich dostępna zarówno w czasie działania, jak i kompilowania.

Używaj tej konfiguracji ostrożnie i tylko z zależnościami, które musisz przejściowo eksportować do innych konsumentów nadrzędnych. 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 czasie 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 biblioteki powinny używać zależności implementation.

compileOnly Gradle dodaje zależność tylko do ścieżki klasy 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 czasu kompilowania – zwykle używane do generowania kodu, ale często nie uwzględniane w wynikach kompilacji – możesz oznaczyć tę bibliotekę jako compileOnly.

Jeśli używasz tej konfiguracji, moduł biblioteki musi zawierać warunek środowiska wykonawczego, który sprawdza, czy zależność jest dostępna, a następnie odpowiednio zmienia swoje działanie, aby mógł nadal działać, jeśli zależność nie jest dostępna. Pomaga to zmniejszyć rozmiar ostatecznej aplikacji, ponieważ nie dodaje zależności przejściowych, które nie są krytyczne.

Uwaga: nie możesz używać konfiguracji compileOnly z zależnościami pliku 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 dodawany do ścieżki klasy kompilacji. Jest to rzadko używane na Androidzie, ale często w aplikacjach serwerowych do udostępniania implementacji logowania. Na przykład biblioteka może używać interfejsu API logowania, 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.
ksp
kapt
annotationProcessor

Te konfiguracje dostarczają biblioteki, które przetwarzają adnotacje i inne symbole w kodzie przed jego skompilowaniem. Zwykle sprawdzają poprawność kodu 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 za pomocą konfiguracji ksp, kapt lub annotationProcessor. Użycie tych konfiguracji poprawia wydajność kompilacji, ponieważ oddziela ścieżkę klasy kompilacji od ścieżki klasy procesora adnotacji. Jeśli Gradle znajdzie procesory adnotacji w ścieżce kompilacji, dezaktywuje unikanie kompilacji, co negatywnie wpływa na czas kompilacji (Gradle 5.0 i nowsze ignorują procesory adnotacji znalezione w ścieżce 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 w ścieżce klasy kompilacji, wygeneruje 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 procesor jest dostępny jako procesor symboli Kotlin, użyj go jako zależności ksp. Szczegółowe informacje o korzystaniu z 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 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 używa tylko kodu źródłowego w języku Java, dołącz go za pomocą annotationProcessor.

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

lintChecks

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

Pamiętaj, że pliki AAR zawierające plik lint.jar będą automatycznie przeprowadzać 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 gwarantuje, że testy będą uruchamiane, gdy użytkownicy będą korzystać z Twojej biblioteki.

lintPublish Użyj tej konfiguracji w projektach bibliotek Androida, aby uwzględnić kontrole lint, które Gradle ma skompilować do pliku lint.jar i umieścić w pakiecie AAR. Spowoduje to, że projekty, które korzystają z Twojego pliku AAR, również będą stosować te testy linta. Jeśli wcześniej używano konfiguracji zależności lintChecks do uwzględniania kontroli linta w opublikowanym pliku AAR, musisz przenieść te zależności, aby używały 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"))
}

Dynamiczny

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 konkretnego zbioru źródeł wariantu kompilacji lub testowego zbioru źródeł, musisz zapisać nazwę konfiguracji wielkimi literami i poprzedzić ją nazwą wariantu kompilacji lub testowego zbioru źródeł.

Aby na przykład dodać zdalną zależność binarną tylko do „bezpłatnego” wariantu usługi za pomocą konfiguracji implementation, użyj tego kodu:

Kotlin

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

Dynamiczny

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

Jeśli jednak chcesz dodać zależność dla wariantu, który łączy wariant usługi 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"))
}

Dynamiczny

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ą, użyj tego kodu:

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

Dynamiczny

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 niektóre konfiguracje nie mają sensu w tej sytuacji. Na przykład inne moduły nie mogą zależeć od androidTest, więc jeśli użyjesz konfiguracji androidTestApi, zobaczysz 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, określa priorytet każdej z nich. Na przykład pierwsza biblioteka ma wyższy priorytet niż druga, a druga ma wyższy priorytet niż trzecia. Ta kolejność jest ważna, gdy zasoby są scalane lub elementy pliku manifestu są scalane z bibliotek w aplikacji.

Jeśli na przykład w projekcie zadeklarujesz:

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

W takim przypadku kolejność zależności będzie następująca:

  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 (który od niego zależy) ma wyższy priorytet niż LIB_B.

Więcej informacji o łączeniu plików manifestu z różnych źródeł lub zależności projektu znajdziesz w artykule o łączeniu wielu plików manifestu.

Informacje o zależnościach w Konsoli Play

Podczas tworzenia aplikacji AGP uwzględnia 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 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 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 dotyczące pakietów SDK

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

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

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

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

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

Dynamiczny

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 od zdalnego pliku binarnego jest skrótem od:

Kotlin

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

Dynamiczny

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ą include: w pliku settings.gradle.kts. Podczas tworzenia aplikacji system kompilacji kompiluje moduł biblioteki i pakuje skompilowaną zawartość w aplikacji.

Plik kompilacji deklaruje też zależność od wtyczki Androida do obsługi Gradle (com.application.android). Jeśli masz kilka modułów, które używają tej samej wtyczki, we wszystkich modułach możesz mieć tylko jedną wersję wtyczki w ścieżce kompilacji. Zamiast określać wersję w każdym skrypcie kompilacji modułu, należy uwzględnić zależność wtyczki w głównym skrypcie kompilacji z wersją i wskazać, aby jej nie stosować. Dodanie apply false informuje Gradle, aby zanotował wersję wtyczki, ale nie używał jej w głównej kompilacji. 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
}

Dynamiczny

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ć skrypt kompilacji na poziomie projektu pusty:

Kotlin

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

Dynamiczny

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