Menambahkan dependensi build

Sistem build Gradle di Android Studio memudahkan Anda menyertakan biner eksternal atau modul library lainnya ke build Anda sebagai dependensi. Dependensi dapat ditemukan di komputer Anda atau di repositori jarak jauh, dan setiap dependensi transitif yang dideklarasikan akan otomatis disertakan. Halaman ini menjelaskan cara menggunakan dependensi bersama project Android Anda, termasuk detail tentang perilaku dan konfigurasi yang spesifik untuk Android Gradle Plugin. Untuk panduan konseptual yang lebih mendalam tentang dependensi Gradle, sebaiknya Anda juga membaca Panduan Gradle untuk pengelolaan dependensi—tetapi ingat bahwa project Android Anda hanya boleh menggunakan konfigurasi dependensi yang ditentukan pada halaman ini.

Jenis-jenis dependensi

Untuk menambahkan dependensi ke project Anda, tentukan konfigurasi dependensi seperti implementation dalam blok dependencies file build.gradle Anda.

Misalnya, file build.gradle berikut untuk sebuah modul aplikasi mencakup tiga jenis dependensi berbeda:

apply plugin: 'com.android.application'

    android { ... }

    dependencies {
        // Dependency on a local library module
        implementation project(":mylibrary")

        // Dependency on local binaries
        implementation fileTree(dir: 'libs', include: ['*.jar'])

        // Dependency on a remote binary
        implementation 'com.example.android:app-magic:12.3'
    }
    

Masing-masing meminta jenis dependensi library berbeda seperti berikut:

Dependensi modul library lokal
implementation project(':mylibrary')

Baris ini mendeklarasikan dependensi pada sebuah modul library Android dengan nama "mylibrary" (nama ini harus sama dengan nama library yang ditentukan dengan include: dalam file settings.gradle). Ketika Anda membuat aplikasi, sistem build akan mengompilasi modul library dan mengemas konten terkompilasi yang dihasilkannya ke dalam APK.

Dependensi biner lokal
implementation fileTree(dir: 'libs', include: ['*.jar'])

Gradle mendeklarasikan dependensi pada file JAR yang ada di dalam direktori module_name/libs/ project Anda (karena Gradle membaca jalur relatif ke file build.gradle).

Atau, Anda dapat menetapkan file tertentu seperti berikut:

implementation files('libs/foo.jar', 'libs/bar.jar')
Dependensi biner jarak jauh
implementation 'com.example.android:app-magic:12.3'

Ini sebenarnya cara pintas untuk berikut ini:

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

Baris ini mendeklarasikan dependensi pada library "app-magic" versi 12.3, di dalam grup namespace "com.example.android".

Catatan: Dependensi jarak jauh seperti ini mengharuskan Anda mendeklarasikan repositori jarak jauh yang sesuai tempat Gradle harus mencari library. Jika library ini belum ada secara lokal, Gradle akan mengambilnya dari situs jarak jauh saat build memerlukannya (seperti saat Anda mengklik Sync Project with Gradle Files atau menjalankan build).

Konfigurasi dependensi

Di dalam blok dependencies, Anda dapat mendeklarasikan dependensi library menggunakan salah satu dari sejumlah konfigurasi dependensi berbeda (misalnya implementation yang ditampilkan di atas). Setiap konfigurasi dependensi menyediakan Gradle dengan petunjuk yang berbeda tentang cara menggunakan dependensi. Tabel berikut menjelaskan setiap konfigurasi yang bisa Anda gunakan untuk dependensi di project Android Anda. Tabel itu juga membandingkan konfigurasi ini dengan konfigurasi yang tidak digunakan lagi pada Android Gradle Plugin 3.0.0.

Konfigurasi baru Konfigurasi yang tidak digunakan lagi Perilaku
implementation compile Gradle menambahkan dependensi ke classpath kompilasi dan mengemas dependensi ke output build. Namun, saat mengonfigurasi dependensi implementation, modul Anda memberi tahu Gradle bahwa Anda tidak ingin modul tersebut membocorkan dependensi ke modul lain pada waktu kompilasi. Artinya, dependensi itu hanya tersedia untuk modul lain selama waktu proses saja.

Menggunakan konfigurasi dependensi ini sebagai ganti api atau compile (tidak digunakan lagi) dapat menghasilkan peningkatan waktu build yang signifikan karena mengurangi jumlah modul yang perlu dikompilasi ulang oleh sistem build. Misalnya, jika dependensi implementation mengubah API-nya, Gradle hanya mengompilasi ulang dependensi itu dan modul yang bergantung langsung padanya. Sebagian besar modul pengujian dan aplikasi akan menggunakan konfigurasi ini.

api compile Gradle menambahkan dependensi ke classpath kompilasi dan output build. Jika menyertakan dependensi api, modul akan memberi tahu Gradle bahwa ia ingin mengekspor dependensi itu secara transitif ke modul lainnya, sehingga dependensi tersebut tersedia untuk modul lain baik selama waktu proses maupun waktu kompilasi.

Konfigurasi ini berperilaku seperti compile (yang sekarang sudah tidak digunakan lagi), tetapi Anda harus menggunakannya dengan hati-hati dan hanya dengan dependensi yang ingin Anda ekspor secara transitif ke konsumen upstream lain. Hal itu karena, jika sebuah dependensi api mengubah API eksternalnya, Gradle akan mengompilasi ulang semua modul yang memiliki akses ke dependensi itu pada waktu kompilasi. Jadi, memiliki banyak dependensi api dapat meningkatkan waktu build secara signifikan. Kecuali jika Anda ingin mengekspos API dependensi ke modul terpisah, modul library sebaiknya menggunakan dependensi implementation saja.

compileOnly provided Gradle menambahkan dependensi ke classpath kompilasi saja (artinya, dependensi tidak ditambahkan ke output build). Ini berguna saat Anda membuat modul Android dan memerlukan dependensi selama kompilasi, tetapi ketersediaannya bersifat opsional selama waktu proses.

Jika Anda menggunakan konfigurasi ini, maka modul library harus menyertakan kondisi waktu proses untuk memeriksa ketersediaan dependensi, lalu mengubah perilakunya dengan lancar agar tetap dapat berfungsi jika tidak disediakan. Hal ini membantu mengurangi ukuran APK akhir dengan tidak menambahkan dependensi sementara yang tidak begitu penting. Konfigurasi ini berperilaku seperti provided (yang sekarang sudah tidak digunakan lagi).

runtimeOnly apk Gradle menambahkan dependensi ke output build saja, untuk digunakan selama waktu proses. Dengan kata lain, dependensi ini tidak ditambahkan ke classpath kompilasi. Konfigurasi ini berperilaku seperti apk (yang sekarang sudah tidak digunakan lagi).
annotationProcessor compile Untuk menambahkan dependensi di sebuah library yang merupakan pemroses anotasi, Anda harus menambahkannya ke classpath pemroses anotasi menggunakan konfigurasi annotationProcessor. Itu karena penggunaan konfigurasi ini meningkatkan performa build dengan memisahkan classpath kompilasi dari classpath pemroses anotasi. Jika menemukan pemroses anotasi pada classpath kompilasi, Gradle akan menonaktifkan pencegahan kompilasi, yang berdampak negatif pada waktu build (Gradle 5.0 dan yang lebih tinggi mengabaikan pemroses anotasi yang ditemukan di classpath kompilasi).

Android Gradle Plugin mengasumsikan dependensi adalah pemroses anotasi jika file JAR-nya berisi file berikut:
META-INF/services/javax.annotation.processing.Processor. Jika plugin mendeteksi pemroses anotasi yang ada pada classpath kompilasi, maka plugin tersebut akan menyebabkan error build.
lintChecks Gunakan konfigurasi ini untuk menyertakan pemeriksaan lint yang harus dijalankan Gradle saat membuat project Anda.

Catatan: Saat menggunakan Android Gradle Plugin 3.4.0 dan yang lebih tinggi, konfigurasi dependensi ini tidak lagi mengemas pemeriksaan lint ke dalam project library Android Anda. Untuk menyertakan dependensi pemeriksaan lint ke dalam library AAR, gunakan konfigurasi lintPublish yang dijelaskan di bawah.

lintPublish Gunakan konfigurasi ini di project library Android untuk menyertakan pemeriksaan lint yang perlu dikompilasi Gradle ke dalam paket dan file lint.jar di AAR Anda. Ini akan menyebabkan project yang menggunakan AAR Anda juga menerapkan pemeriksaan lint tersebut. Jika sebelumnya menggunakan konfigurasi dependensi lintChecks untuk menyertakan pemeriksaan lint dalam AAR yang dipublikasikan, Anda harus memigrasikan dependensi tersebut agar menggunakan konfigurasi lintPublish.

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

Konfigurasi di atas menerapkan dependensi ke semua varian build. Jika ingin mendeklarasikan dependensi hanya untuk set sumber varian build tertentu atau untuk set sumber pengujian, Anda harus membuat nama konfigurasi yang dimulai dengan huruf besar dan memberinya awalan dengan nama varian build atau set sumber pengujian.

Misalnya, untuk menambahkan dependensi implementation saja ke ragam produk "free" (menggunakan dependensi biner jarak jauh), caranya adalah seperti ini:

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

Namun, jika ingin menambahkan dependensi untuk varian yang menggabungkan ragam produk dan jenis build, maka Anda harus menginisialisasi nama konfigurasi di blok configurations. Contoh berikut menambahkan dependensi runtimeOnly ke varian build "freeDebug" (menggunakan dependensi biner lokal):

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

    dependencies {
        freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
    }
    

Untuk menambahkan dependensi implementation bagi pengujian lokal dan pengujian berinstrumen adalah seperti ini:

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 'com.android.support.test.espresso:espresso-core:3.0.2'
    }
    

Namun, konfigurasi tertentu tidak cocok dengan situasi ini. Misalnya, karena modul lainnya tidak dapat bergantung pada androidTest, Anda akan mendapatkan peringatan berikut jika menggunakan konfigurasi androidTestApi:

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

Menambahkan pemroses anotasi

Jika menambahkan pemroses anotasi ke classpath kompilasi, Anda akan melihat pesan error yang mirip dengan berikut ini:

    Error: Annotation processors must be explicitly declared now.
    

Untuk mengatasi error ini, tambahkan pemroses anotasi ke project Anda dengan mengonfigurasi dependensi menggunakan annotationProcessor seperti ditunjukkan di bawah ini:

    dependencies {
        // Adds libraries defining annotations to only the compile classpath.
        compileOnly 'com.google.dagger:dagger:version-number'
        // Adds the annotation processor dependency to the annotation processor classpath.
        annotationProcessor 'com.google.dagger:dagger-compiler:version-number'
    }
    

Catatan: Android Gradle Plugin 3.0.0+ tidak lagi mendukung plugin android-apt.

Meneruskan argumen ke pemroses anotasi

Jika perlu meneruskan argumen ke pemroses anotasi, Anda dapat melakukannya menggunakan blok AnnotationProcessorOptions di konfigurasi build modul. Misalnya, jika ingin meneruskan jenis data dasar sebagai key-value pair, Anda dapat menggunakan properti argument, seperti ditunjukkan di bawah ini:

android {
        ...
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    argument "key1", "value1"
                    argument "key2", "value2"
                }
            }
        }
    }
    

Namun, saat menggunakan Android Gradle Plugin 3.2.0 dan yang lebih tinggi, Anda harus meneruskan argumen pemroses yang mewakili file atau direktori menggunakan antarmuka CommandLineArgumentProvider Gradle.

Penggunaan CommandLineArgumentProvider memungkinkan Anda atau penulis pemroses anotasi untuk meningkatkan kebenaran dan performa build inkremental dan build bersih yang di-cache dengan menerapkan anotasi jenis properti build inkremental ke setiap argumen.

Misalnya, class di bawah ini mengimplementasikan CommandLineArgumentProvider dan menganotasi setiap argumen untuk pemroses. Contoh itu juga menggunakan sintaks bahasa Groovy dan disertakan langsung dalam file build.gradle modul.

class MyArgsProvider implements CommandLineArgumentProvider {

        // Annotates each directory as either an input or output for the
        // annotation processor.
        @InputFiles
        // Using this annotation helps Gradle determine which part of the file path
        // should be considered during up-to-date checks.
        @PathSensitive(PathSensitivity.RELATIVE)
        FileCollection inputDir

        @OutputDirectory
        File outputDir

        // The class constructor sets the paths for the input and output directories.
        MyArgsProvider(FileCollection input, File output) {
            inputDir = input
            outputDir = output
        }

        // Specifies each directory as a command line argument for the processor.
        // The Android plugin uses this method to pass the arguments to the
        // annotation processor.
        @Override
        Iterable<String> asArguments() {
            // Use the form '-Akey[=value]' to pass your options to the Java compiler.
            ["-AinputDir=${inputDir.singleFile.absolutePath}",
             "-AoutputDir=${outputDir.absolutePath}"]
        }
    }

    android {...}
    

Setelah membuat class yang mengimplementasikan CommandLineArgumentProvider, Anda perlu menginisialisasi dan meneruskannya ke plugin Android menggunakan properti annotationProcessorOptions.compilerArgumentProvider, seperti ditunjukkan di bawah ini.

// This is in your module's build.gradle file.
    android {
        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    // Creates a new MyArgsProvider object, specifies the input and
                    // output paths for the constructor, and passes the object
                    // to the Android plugin.
                    compilerArgumentProvider new MyArgsProvider(files("input/path"),
                                             new File("output/path"))
                }
            }
        }
    }
    

Untuk mempelajari lebih lanjut bagaimana implementasi CommandLineArgumentProvider membantu meningkatkan performa build, baca Membuat cache project Java.

Menonaktifkan pemeriksaan error pemroses anotasi

Jika memiliki dependensi pada classpath kompilasi yang menyertakan pemroses anotasi yang tidak diperlukan, Anda dapat menonaktifkan pemeriksaan error dengan menambahkan baris berikut ke file build.gradle Anda. Perlu diingat, pemroses anotasi yang Anda tambahkan ke classpath kompilasi tetap tidak ditambahkan ke classpath pemroses.

android {
        ...
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    includeCompileClasspath false
                }
            }
        }
    }
    

Jika mengalami masalah setelah memigrasikan pemroses anotasi project ke classpath pemroses, Anda dapat mengizinkan pemroses anotasi di classpath kompilasi dengan menetapkan includeCompileClasspath ke true. Namun, sebaiknya jangan menetapkan properti ini ke true, dan opsi untuk melakukannya akan dihapus pada update mendatang plugin Android.

Mengecualikan dependensi transitif

Seiring bertambahnya cakupan aplikasi, aplikasi dapat berisi sejumlah dependensi termasuk dependensi langsung dan dependensi transitif (library yang bergantung pada library yang diimpor oleh aplikasi Anda). Untuk mengecualikan dependensi transitif yang sudah tidak diperlukan lagi, Anda dapat menggunakan kata kunci exclude seperti ditunjukkan di bawah ini:

dependencies {
        implementation('some-library') {
            exclude group: 'com.example.imgtools', module: 'native'
        }
    }
    

Mengecualikan dependensi transitif dari konfigurasi pengujian

Jika Anda perlu mengecualikan dependensi transitif tertentu dari pengujian, contoh kode yang ditunjukkan di atas mungkin tidak berfungsi sesuai harapan. Hal itu karena konfigurasi pengujian (misalnya, androidTestImplementation) memperluas konfigurasi implementation modul. Dengan kata lain, konfigurasi pengujian selalu berisi dependensi implementation saat Gradle mengatasi konfigurasi ini.

Jadi, untuk mengecualikan dependensi transitif dari pengujian, Anda harus melakukannya pada waktu eksekusi, seperti ditunjukkan di bawah ini:

android.testVariants.all { variant ->
        variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
        variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    }
    

Catatan: Anda masih dapat menggunakan kata kunci exclude dalam blok dependensi seperti ditunjukkan dalam contoh kode asli dari bagian Mengecualikan dependensi untuk menghilangkan dependensi transitif yang khusus untuk konfigurasi pengujian dan tidak termasuk dalam konfigurasi lain.

Menggunakan manajemen dependensi sadar-varian

Plugin Android 3.0.0 dan yang lebih tinggi menyertakan mekanisme dependensi baru yang otomatis mencocokkan varian saat menggunakan library. Ini berarti varian debug aplikasi otomatis menggunakan varian debug library, dan seterusnya. Plugin ini juga berfungsi saat menggunakan ragam—varian freeDebug aplikasi akan menggunakan varian freeDebug library.

Agar plugin mencocokkan varian secara akurat, Anda perlu menyediakan fallback pencocokan untuk instance bila pencocokan langsung tidak memungkinkan. Pertimbangkan jika aplikasi Anda mengonfigurasi jenis build yang disebut "staging", tetapi salah satu dependensi library-nya tidak. Saat mencoba membuat versi "staging" aplikasi Anda, plugin tidak akan tahu versi library mana yang digunakan, dan Anda akan melihat pesan error yang mirip dengan berikut ini:

    Error:Failed to resolve: Could not resolve project :mylibrary.
    Required by:
        project :app
    

Mengatasi error build yang berkaitan dengan pencocokan varian

Plugin menyertakan elemen DSL untuk membantu Anda mengontrol bagaimana Gradle harus mengatasi situasi ketika pencocokan varian langsung antara aplikasi dan dependensi tidak mungkin dilakukan. Lihat tabel di bawah ini untuk menentukan properti DSL mana yang harus Anda gunakan untuk mengatasi error build tertentu yang terkait dengan pencocokan dependensi yang sadar-varian.

Penyebab error buildPenyelesaian

Aplikasi Anda menyertakan jenis build yang tidak disertakan pada dependensi library.

Misalnya, aplikasi Anda menyertakan jenis build "staging", tetapi dependensi hanya menyertakan jenis build "debug" dan "release".

Perhatikan, tidak apa-apa jika dependensi library menyertakan jenis build yang tidak disertakan pada aplikasi Anda. Itu semata-mata karena plugin tidak pernah meminta jenis build tersebut dari dependensi.

Gunakan matchingFallbacks untuk menentukan kecocokan alternatif bagi jenis build tertentu, seperti ditunjukkan di bawah ini:


    // In the app's build.gradle file.
    android {
        buildTypes {
            debug {}
            release {}
            staging {
                // Specifies a sorted list of fallback build types that the
                // plugin should try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks = ['debug', 'qa', 'release']
            }
        }
    }
    

Untuk dimensi ragam tertentu yang ada dalam aplikasi dan dependensi library-nya, aplikasi Anda menyertakan ragam yang tidak disertakan pada library.

Misalnya, aplikasi Anda dan dependensi library-nya menyertakan dimensi ragam "tier". Namun, dimensi "tier" dalam aplikasi menyertakan ragam "free" dan "paid", sementara dependensi hanya menyertakan ragam "demo" dan "paid" untuk dimensi yang sama.

Perhatikan, untuk dimensi ragam tertentu yang ada di aplikasi dan dependensi library-nya, tidak apa-apa jika library menyertakan ragam produk yang tidak disertakan pada aplikasi Anda. Hal itu semata-mata karena plugin tidak pernah meminta ragam itu dari dependensi.

Gunakan matchingFallbacks untuk menentukan kecocokan alternatif bagi ragam produk "free" aplikasi, seperti ditunjukkan di bawah ini:


    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Do not configure matchingFallbacks in the defaultConfig block.
        // Instead, you must specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions 'tier'
        productFlavors {
            paid {
                dimension 'tier'
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            free {
                dimension 'tier'
                // Specifies a sorted list of fallback flavors that the plugin
                // should try to use when a dependency's matching dimension does
                // not include a "free" flavor. You may specify as many
                // fallbacks as you like, and the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks = ['demo', 'trial']
            }
        }
    }
    

Sebuah dependensi library menyertakan dimensi ragam yang tidak disertakan pada aplikasi Anda.

Misalnya, dependensi library menyertakan ragam untuk dimensi "minApi", sementara aplikasi Anda hanya menyertakan ragam untuk dimensi "tier". Jadi, saat Anda ingin membuat versi "freeDebug" untuk aplikasi, plugin tidak tahu apakah akan menggunakan versi dependensi "minApi23Debug" atau "minApi18Debug".

Perhatikan, tidak apa-apa jika aplikasi Anda menyertakan dimensi ragam yang tidak disertakan pada dependensi library. Hal itu karena plugin tersebut hanya mencocokkan ragam dari dimensi yang ada pada dependensi. Misalnya, jika sebuah dependensi tidak menyertakan dimensi untuk ABI, versi "freeX86Debug" aplikasi Anda hanya akan menggunakan versi "freeDebug" dependensi.

Gunakan missingDimensionStrategy dalam blok defaultConfig untuk menentukan ragam default yang harus dipilih plugin dari setiap dimensi yang hilang, seperti ditunjukkan dalam contoh di bawah. Anda juga dapat mengganti pilihan pada blok productFlavors, sehingga setiap ragam dapat menetapkan strategi pencocokan berbeda untuk dimensi yang hilang.


    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin should try to use from
        // a given dimension. The following tells the plugin that, when encountering
        // a dependency that includes a "minApi" dimension, it should select the
        // "minApi18" flavor. You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
        // You should specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy 'abi', 'x86', 'arm64'
        }
        flavorDimensions 'tier'
        productFlavors {
            free {
                dimension 'tier'
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the "minApi" dimension.
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
            }
            paid {}
        }
    }
    

Mengonfigurasi dependensi aplikasi Wear OS

Mengonfigurasi dependensi untuk modul Wear OS mirip dengan modul lainnya. Artinya, modul Wear OS menggunakan konfigurasi dependensi yang sama, seperti implementation dan compileOnly.

Modul Wear juga mendukung manajemen dependensi sadar-varian. Oleh karena itu, jika modul aplikasi dasar Anda memiliki dependensi pada modul Wear, setiap varian dari modul dasar menggunakan varian yang cocok dengan modul Wear. Jika membuat aplikasi sederhana dengan dependensi hanya pada satu modul Wear, di mana modul tersebut mengonfigurasi varian yang sama dengan modul dasar, maka Anda perlu menentukan konfigurasi wearApp dalam file build.gradle modul dasar Anda seperti ditunjukkan di bawah ini:

dependencies {
        // If the main and Wear app modules have the same variants,
        // variant-aware dependency management automatically matches
        // variants of the main app module with that of the wear module.
        wearApp project(':wearable')
    }
    

Jika memiliki beberapa modul Wear dan ingin menentukan modul Wear berbeda untuk setiap ragam aplikasi, Anda dapat melakukannya dengan menggunakan konfigurasi flavorWearApp, sebagai berikut (tetapi Anda tidak dapat menyertakan dependensi lain yang menggunakan konfigurasi wearApp):

dependencies {
        paidWearApp project(':wear1')
        demoWearApp project(':wear1')
        freeWearApp project(':wear2')
    }
    

Repositori jarak jauh

Saat dependensi Anda adalah sesuatu selain library lokal atau hierarki file, Gradle akan mencari file tersebut di repositori online mana pun yang ditetapkan dalam blok repositories file build.gradle Anda. Urutan tempat Anda mencantumkan masing-masing repositori menentukan urutan di mana Gradle mencari repositori untuk setiap dependensi project. Misalnya, jika sebuah dependensi tersedia dari repositori A dan B, dan Anda mencantumkan A terlebih dahulu, Gradle akan mendownload dependensi dari repositori A.

Secara default, project Android Studio baru akan menetapkan repositori Maven Google dan JCenter sebagai lokasi repositori dalam file build.gradle tingkat atas project, seperti ditunjukkan di bawah ini:

allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    

Jika Anda menginginkan sesuatu dari repositori pusat Maven, maka tambahkan mavenCentral(), atau untuk repositori lokal, gunakan mavenLocal():

allprojects {
        repositories {
            google()
            jcenter()
            mavenCentral()
            mavenLocal()
        }
    }
    

Atau Anda dapat mendeklarasikan repositori Maven atau Ivy tertentu seperti berikut:

allprojects {
        repositories {
            maven {
                url "https://repo.example.com/maven2"
            }
            maven {
                url "file://local/repo/"
            }
            ivy {
                url "https://repo.example.com/ivy"
            }
        }
    }
    

Untuk informasi selengkapnya, lihat Panduan Repositori Gradle.

Repositori Maven Google

Versi terbaru library Android berikut tersedia dari repositori Maven Google:

Anda dapat melihat semua artefak yang tersedia di indeks repositori Maven Google (lihat di bawah untuk akses terprogram).

Untuk menambahkan salah satu library ini ke build Anda, sertakan repositori Maven Google di file build.gradle tingkat atas:

allprojects {
        repositories {
            google()

            // If you're using a version of Gradle lower than 4.1, you must instead use:
            // maven {
            //     url 'https://maven.google.com'
            // }
            // An alternative URL is 'https://dl.google.com/dl/android/maven2/'
        }
    }
    

Kemudian tambahkan library yang diinginkan ke blok dependencies modul Anda. Misalnya, library appcompat akan terlihat seperti ini:

dependencies {
        implementation 'com.android.support:appcompat-v7:28.0.0'
    }
    

Namun, jika Anda mencoba menggunakan versi yang lebih lama dari library di atas dan dependensi Anda gagal, maka library tersebut tidak akan tersedia di repositori Maven dan sebagai gantinya Anda harus mendapatkan library dari repositori offline.

Akses terprogram

Untuk akses terprogram ke artefak Maven Google, Anda dapat memperoleh daftar XML grup artefak dari maven.google.com/master-index.xml. Kemudian, untuk grup apa saja, Anda dapat melihat nama dan versi library tersebut di:

maven.google.com/group_path/group-index.xml

Misalnya, library di grup android.arch.lifecycle dicantumkan di maven.google.com/android/arch/lifecycle/group-index.xml.

Anda juga bisa mendownload file POM dan JAR di:

maven.google.com/group_path/library/version /library-version.ext

Misalnya: maven.google.com/android/arch/lifecycle/compiler/1.0.0/compiler-1.0.0.pom.

Repositori offline dari SDK Manager

Untuk library yang tidak tersedia dari repositori Maven Google (biasanya versi library yang lebih lama), Anda harus mendownload paket offline Google Repository dari SDK Manager.

Selanjutnya, Anda dapat menambahkan library ini ke blok dependencies seperti biasa.

Library offline disimpan di android_sdk/extras/.

Urutan dependensi

Urutan pencantuman dependensi menunjukkan prioritas untuk setiap library: library pertama memiliki prioritas lebih tinggi daripada library kedua, library kedua memiliki prioritas lebih tinggi daripada library ketiga, dan seterusnya. Urutan ini penting jika resource digabungkan atau elemen manifes digabungkan ke dalam aplikasi Anda dari library.

Misalnya, jika project Anda mendeklarasikan berikut ini:

  • Dependensi pada LIB_A dan LIB_B (dalam urutan seperti itu)
  • Dan LIB_A bergantung pada LIB_C dan LIB_D (dalam urutan seperti itu)
  • Serta LIB_B juga bergantung pada LIB_C

Maka, urutan dependensi rata akan menjadi seperti berikut:

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

Ini memastikan bahwa baik LIB_A maupun LIB_B dapat menggantikan LIB_C; dan LIB_D masih lebih tinggi prioritasnya daripada LIB_B karena LIB_A (yang bergantung padanya) memiliki prioritas lebih tinggi daripada LIB_B.

Untuk informasi selengkapnya tentang bagaimana manifes dari sumber/dependensi project yang berbeda digabungkan, lihat Menggabungkan beberapa file manifes.

Melihat dependensi modul

Sebagian dependensi langsung mungkin memiliki dependensi sendiri. Dependensi semacam ini disebut dependensi transitif. Bukannya mengharuskan Anda mendeklarasikan setiap dependensi transitif secara manual, Gradle mengumpulkan dan menambahkannya secara otomatis. Android Gradle Plugin menyediakan tugas yang menampilkan daftar dependensi yang diselesaikan Gradle untuk modul tertentu.

Untuk setiap modul, laporan juga mengelompokkan dependensi berdasarkan varian build, set sumber pengujian, dan classpath. Berikut ini adalah contoh laporan untuk classpath waktu proses modul aplikasi dari varian build debug-nya dan classpath kompilasi dari set sumber pengujian berinstrumen.

debugRuntimeClasspath - Dependencies for runtime/packaging
    +--- :mylibrary (variant: debug)
    +--- com.google.android.material:material:1.0.0@aar
    +--- androidx.appcompat:appcompat:1.0.2@aar
    +--- androidx.constraintlayout:constraintlayout:1.1.3@aar
    +--- androidx.fragment:fragment:1.0.0@aar
    +--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
    +--- androidx.recyclerview:recyclerview:1.0.0@aar
    +--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
    ...

    debugAndroidTest
    debugAndroidTestCompileClasspath - Dependencies for compilation
    +--- androidx.test.ext:junit:1.1.0@aar
    +--- androidx.test.espresso:espresso-core:3.1.1@aar
    +--- androidx.test:runner:1.1.1@aar
    +--- junit:junit:4.12@jar
    ...
    

Untuk menjalankan tugas, lakukan seperti berikut:

  1. Pilih View > Tool Windows > Gradle (atau klik Gradle dalam panel jendela fitur).
  2. Luaskan NamaAplikasi > Tasks > android, lalu klik dua kali androidDependencies. Setelah Gradle mengeksekusi tugas, jendela Run akan terbuka untuk menampilkan output.

Untuk informasi selengkapnya tentang mengelola dependensi dalam Gradle, lihat Dasar-dasar manajemen dependensi di Panduan Pengguna Gradle.

Memperbaiki error penyelesaian dependensi

Saat Anda menambahkan beberapa dependensi ke project aplikasi, dependensi langsung dan dependensi transitif tersebut mungkin berkonflik satu sama lain. Android Gradle Plugin mencoba mengatasi konflik ini dengan mulus, tetapi beberapa konflik dapat menyebabkan error waktu kompilasi atau error waktu proses.

Untuk membantu Anda menyelidiki dependensi mana yang mengakibatkan error, periksa hierarki dependensi aplikasi Anda dan temukan dependensi yang muncul lebih dari sekali, atau yang muncul dengan versi yang berkonflik.

Jika Anda tidak dapat mengenali dependensi duplikat dengan mudah, cobalah menggunakan UI Android Studio untuk menelusuri dependensi yang menyertakan class duplikat seperti berikut:

  1. Pilih Navigate > Class dari panel menu.
  2. Dalam dialog penelusuran pop-up, pastikan kotak di samping Include non-project items dicentang.
  3. Ketikkan nama class yang muncul dalam error build.
  4. Periksa hasilnya untuk dependensi yang menyertakan class tersebut.

Bagian berikut ini menjelaskan berbagai jenis error penyelesaian dependensi yang mungkin Anda jumpai dan cara memperbaikinya.

Memperbaiki error class duplikat

Jika sebuah class muncul lebih dari sekali pada classpath waktu proses, Anda akan mendapat error yang mirip dengan berikut:

    Program type already present com.example.MyClass
    

Error ini biasanya terjadi akibat salah satu keadaan berikut:

  • Sebuah dependensi biner menyertakan library yang juga disertakan oleh aplikasi Anda sebagai dependensi langsung. Misalnya, aplikasi Anda menyatakan dependensi langsung pada Library A dan Library B, tetapi Library A sudah menyertakan Library B dalam binernya.
    • Untuk mengatasi masalah ini, hapus Library B sebagai dependensi langsung.
  • Aplikasi Anda memiliki dependensi biner lokal dan dependensi biner jarak jauh pada library yang sama.
    • Untuk mengatasi masalah ini, hapus salah satu dependensi biner.

Mengatasi konflik antara classpath

Saat menangani classpath kompilasi, Gradle akan menangani classpath waktu proses terlebih dahulu dan menggunakan hasilnya untuk menentukan versi dependensi apa yang harus ditambahkan ke classpath kompilasi. Dengan kata lain, classpath waktu proses menentukan nomor versi yang diperlukan untuk dependensi identik pada classpath downstream.

classpath waktu proses aplikasi Anda juga menentukan nomor versi yang diperlukan Gradle untuk mencocokkan dependensi dalam classpath waktu proses untuk APK pengujian aplikasi. Hierarki classpath dijelaskan pada Gambar 1.

Gambar 1. Nomor versi dependensi yang muncul di beberapa classpath harus cocok, sesuai dengan hierarki ini.

Konflik ketika versi berbeda dari dependensi yang sama muncul di beberapa classpath dapat terjadi jika, misalnya, aplikasi Anda menyertakan versi dependensi menggunakan konfigurasi dependensi implementation, sementara modul library menyertakan versi dependensi yang berbeda menggunakan konfigurasi runtimeOnly.

Saat menyelesaikan dependensi pada classpath waktu proses dan classpath waktu kompilasi, Android Gradle Plugin 3.3.0 dan yang lebih tinggi mencoba untuk memperbaiki konflik versi downstream tertentu secara otomatis. Misalnya, jika classpath waktu proses menyertakan Library A versi 2.0 dan classpath kompilasi menyertakan Library A versi 1.0, maka plugin akan otomatis mengupdate dependensi pada classpath kompilasi ke Library A versi 2.0 untuk menghindari error.

Namun, jika classpath waktu proses menyertakan Library A versi 1.0 dan classpath kompilasi menyertakan Library A versi 2.0, plugin tidak akan mendowngrade dependensi pada classpath kompilasi ke Library A versi 1.0, dan Anda tetap mendapatkan error yang mirip dengan berikut ini:

    Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'.
    Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.
    

Untuk mengatasi masalah ini, lakukan salah satu dari berikut ini:

  • Sertakan versi yang diinginkan dari dependensi tersebut sebagai dependensi api ke modul library Anda. Artinya, hanya modul library Anda yang mendeklarasikan dependensi, tetapi modul aplikasi juga akan memiliki akses ke API-nya, secara transitif.
  • Atau, Anda dapat mendeklarasikan dependensi pada kedua modul, tetapi Anda harus memastikan bahwa setiap modul menggunakan versi dependensi yang sama. Pelajari cara mengonfigurasi properti di seluruh project untuk memastikan versi setiap dependensi tetap konsisten di seluruh project Anda.

Menerapkan logika build kustom

Bagian ini menjelaskan topik-topik lanjutan yang berguna jika Anda ingin memperluas Android Gradle Plugin atau menulis plugin Anda sendiri.

Memublikasikan varian dependensi ke logika kustom

Library dapat memiliki fungsionalitas yang mungkin ingin digunakan oleh project atau subproject lain. Memublikasikan library adalah proses yang menjadikan library tersebut tersedia bagi konsumennya. Library dapat mengontrol dependensi mana saja yang dapat diakses oleh konsumennya pada waktu kompilasi dan waktu proses.

Ada dua konfigurasi terpisah yang menahan dependensi transitif dari setiap classpath yang harus digunakan oleh konsumennya agar dapat memakai library seperti yang dijelaskan di bawah ini:

  • variant_nameApiElements: Konfigurasi ini menahan dependensi transitif yang tersedia bagi konsumen pada waktu kompilasi.
  • variant_nameRuntimeElements: Konfigurasi ini menahan dependensi transitif yang tersedia bagi konsumen pada waktu proses.

Untuk mempelajari lebih lanjut hubungan antara berbagai konfigurasi, baca Konfigurasi plugin library Java.

Menyesuaikan strategi penyelesaian dependensi

Sebuah project mungkin menyertakan dependensi pada dua versi berbeda dari library yang sama, dan hal ini dapat mengakibatkan konflik dependensi. Misalnya, jika project Anda bergantung pada modul A versi 1 dan modul B versi 2, dan modul A secara transitif bergantung pada modul B versi 3, maka akan muncul konflik versi dependensi.

Untuk mengatasi konflik ini, Android Gradle Plugin menggunakan strategi penyelesaian dependensi berikut: saat plugin mendeteksi bahwa versi berbeda dari modul yang sama terdapat dalam grafik dependensi, maka secara default plugin akan memilih dependensi dengan nomor versi tertinggi.

Akan tetapi, strategi ini mungkin tidak selalu berfungsi seperti yang Anda inginkan. Untuk menyesuaikan strategi penyelesaian dependensi, gunakan konfigurasi berikut untuk menyelesaikan dependensi spesifik dari varian yang diperlukan untuk tugas Anda:

  • variant_nameCompileClasspath: Konfigurasi ini berisi strategi penyelesaian untuk classpath kompilasi varian tertentu.
  • variant_nameRuntimeClasspath: Konfigurasi ini berisi strategi penyelesaian untuk classpath waktu proses varian tertentu.

Android Gradle Plugin menyertakan getter yang dapat Anda gunakan untuk mengakses objek konfigurasi dari setiap varian. Dengan demikian, Anda dapat menggunakan varian API untuk mengkueri penyelesaian dependensi seperti ditunjukkan pada contoh di bawah ini:

    android {
        applicationVariants.all { variant ->
            // Return compile configuration objects of a variant.
            variant.getCompileConfiguration().resolutionStrategy {
            // Use Gradle's ResolutionStrategy API
            // to customize how this variant resolves dependencies.
                ...
            }
            // Return runtime configuration objects of a variant.
            variant.getRuntimeConfiguration().resolutionStrategy {
                ...
            }
            // Return annotation processor configuration of a variant.
            variant.getAnnotationProcessorConfiguration().resolutionStrategy {
                ...
            }
        }
    }