Save the date! Android Dev Summit is coming to Sunnyvale, CA on Oct 23-24, 2019.

Menambahkan dependensi build

Sistem build Gradle di Android Studio memudahkan Anda menyertakan biner eksternal atau modul library lainnya ke build sebagai dependensi. Dependensi bisa ditemukan di mesin Anda atau di repositori jarak jauh, dan dependensi transitif yang dideklarasikannya secara otomatis turut disertakan. Halaman ini menjelaskan cara menggunakan dependensi bersama project Android Anda, termasuk detail tentang perilaku dan konfigurasi yang spesifik untuk Android Plugin for Gradle. Untuk panduan konsep yang lebih mendalam untuk dependensi Gradle, Anda juga harus melihat panduan Gradle untuk manajemen dependensi—tetapi ingatlah bahwa project Android Anda hanya boleh menggunakan konfigurasi dependensi yang ditentukan pada halaman ini.

Tipe dependensi

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

Misalnya, file build.gradle berikut untuk modul aplikasi menyertakan tiga macam dependensi:

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

Ini mendeklarasikan dependensi pada sebuah Modul library Android bernama "mylibrary" (nama ini harus sama dengan nama library yang didefinisikan dengan include: di file settings.gradle). Ketika Anda membuat aplikasi Anda, sistem build system mengkompilasi modul library dan mengemas konten dikompilasi yang dihasilkan di APK.

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

Gradle mendeklarasikan dependensi di file JAR dalam direktori project Anda module_name/libs/ (karena Gradle membaca lokasi bergantung pada file build.gradle).

Atau, Anda dapat menetapkan file individual seperti berikut:

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

Ini sebenarnya cara pintas untuk yang berikut ini:

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

Ini mendeklarasikan dependensi pada versi 12.3 library "app-magic", di dalam grup namespace "code.example.android".

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

Konfigurasi dependensi

Di dalam blok dependencies, Anda bisa mendeklarasikan dependensi library dengan menggunakan salah satu dari sejumlah konfigurasi dependensi yang 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 Plugin Android Gradle 3.0.0.

Konfigurasi baru Konfigurasi yang tidak digunakan lagi Perilaku
implementation compile Gradle menambahkan dependensi ke classpath kompilasi dan mengemas dependensi ke keluaran build. Akan tetapi, ketika modul Anda mengonfigurasi dependensi implementation, itu memberi tahu Gradle jika Anda tidak ingin modul memnocorkan dependensi ke modul lain pada waktu kompilasi. Artinya, dependensi tersedia untuk modul lain hanya pada waktu proses.

Menggunakan konfigurasi dependensi ini sebagai ganti api atau compile (tidak digunakan lagi) bisa mengakibatkan perbaikan waktu build yang signifikan karena mengurangi jumlah modul yang perlu dikompilasi ulang 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 semestinya menggunakan konfigurasi ini.

api compile Gradle menambahkan dependensi ke classpath kompilasi dan keluaran build. Bila sebuah modul menyertakan dependensi api, hal ini akan memungkinkan Gradle mengetahui bahwa modul tersebut ingin mengekspor secara transitif dependensi itu ke modul lainnya, sehingga dependensi itu tersedia untuk modul lain baik pada 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. Sehingga, memiliki banyak dependensi api secara signifikan bisa menambah waktu build. Kecuali jika Anda ingin mengekspos API dependensi ke modul pengujian terpisah, maka sebagai gantinya modul library harus menggunakan dependensi implementation .

compileOnly provided Gradle menambahkan dependensi ke classpath kompilasi saja (artinya, dependensi tidak ditambahkan ke keluaran build). Ini berguna bila Anda membuat modul Android dan Anda memerlukan dependensi selama kompilasi, tetapi itu opsional untuk menyediakannya pada waktu proses.

Jika Anda menggunakan konfigurasi ini, maka modul library Anda harus menyertakan syarat waktu proses yang akan diperiksa apakah dependensi tersedia, kemudian mengubah perilakunya dengan lancar agar tetap bisa berfungsi jika tidak disediakan. Hal ini membantu mengurangi ukuran APK final 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 keluaran build saja, untuk digunakan selama waktu proses. Dengan kata lain, ini tidak ditambahkan ke classpath kompilasi. Konfigurasi ini berperilaku seperti apk (yang sekarang sudah tidak digunakan lagi).
annotationProcessor compile Untuk menambahkan dependensi di library yang merupakan prosesor anotasi, Anda harus menambahkannya ke classpath prosesor anotasi menggunakan konfigurasi annotationProcessor. Itu karena menggunakan konfigurasi ini meningkatkan kinerja build dengan memisahkan classpath kompilasi dari classpath prosesor anotasi. Jika Gradle menemukan prosesor anotasi di classpath kompilasi, Gradle akan menonaktifkan pencegahan kompilasi, yang akan berdampak negatif pada waktu build (Gradle 5.0 dan yang lebih tinggi menolak prosesor anotasi yang ditemukan di classpath kompilasi).

Plugin Android Gradle mengasumsikan dependensi adalah prosesor anotasi jika file JAR-nyaberisi file berikut:
META-INF/services/javax.annotation.processing.Processor. Jika plugin mendeteksi prosesor anotasi yang ada pada classpath kompilasi, maka itu akan menyebabkan error build.

Konfigurasi di atas berlaku untuk set sumber utama project Anda, yang diterapkan pada semua varian build. Jika Anda malah ingin mendeklarasikan dependensi hanya untuk set sumber tertentu varian build atau untuk set sumber pengujian, Anda harus membuat nama konfigurasi dalam huruf besar dan memberinya awalan dengan nama varian build atau set sumber pengujian.

Misalnya, untuk menambahkan sebuah dependensi implementation hanya ke ragam produk "free"(dengan menggunakan dependensi biner jauh), maka akan terlihat seperti ini:

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

Akan tetapi, jika Anda ingin menambahkan dependensi untuk varian yang menggabungkan ragam produk dan tipe build, maka Anda harus melakukan inisialiasi nama konfigurasi di blok configurations. Contoh berikut menambahkan sebuah dependensi runtimeOnly ke varian build "freeDebug" (dengan 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 instrumentasi , maka akan terlihat 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'
}

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

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

Menambahkan prosesor anotasi

Jika Anda menambahkan prosesor anotasi ke classpath kompilasi, Anda akan melihat pesan error yang serupa dengan yang berikut:

Error: Annotation processors must be explicitly declared now.

Untuk mengatasi error ini, tambahkan prosesor anotasi ke project Anda dengan mengonfigurasi dependensi menggunakan annotationProcessor seperti yang ditampilkan 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 Plugin for Gradle 3,0.0+ tidak lagi mendukung plugin android-apt.

Meneruskan argumen ke prosesor anotasi

Jika Anda harus meneruskan argumen ke prosesor anotasi, Anda dapat melakukannya menggunakan blok AnnotationProcessorOptions di konfigurasi build modul. Misalnya, jika Anda ingin meneruskan tipe data sederhaha seperti key-value pair, Anda bisa menggunakan properti argument, seperti yang ditampilkan di bawah ini:

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

Akan tetapi, ketika menggunakan plugin Android Gradle 3.2.0 dan yang lebih tinggi, Anda harus meneruskan argumen prosesor yang mewaliki file atau direktori menggunakan antarmuka CommandLineArgumentProvider Gradle.

Menggunakan CommandLineArgumentProvider memungkinkan Anda atau penulis prosesor anotasi untuk meningkatkan keakuratan dan kinerja dari build tambahan dan build bersih cache dengan menerapkan properti build tambahan tipe anotasi ke setiap argumen.

Misalnya, class di bawah ini mengimplementasikan CommandLineArgumentProvider dan menganotasikan setiap argumen untuk prosesor. 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 Anda membuat class yang mengimplementasikan CommandLineArgumentProvider, Anda perlu melakukan inisialiasi dan meneruskannya ke plugin Android menggunakan properti annotationProcessorOptions.compilerArgumentProvider , seperti yang ditampilkan 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 tentang bagaimana mengimplementasikan CommandLineArgumentProvider membantu meningkatkan kinerja build, baca project Caching Java.

Menonaktifkan pemeriksaan error prosesor anotasi

Bila Anda memiliki dependensi pada classpath kompilasi yang menyertakan prosesor anotasi yang tidak dibutuhkan, Anda bisa menonaktifkan pemeriksaan error dengan menambahkan yang berikut ini ke file build.gradle Anda. Perlu diingat, prosesor anotasi yang Anda tambahkan ke classpath kompilasi tetap tidak ditambahkan ke classpath prosesor.

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

Jika Anda mengalami masalah setelah memindahkan prosesor anotasi project ke classpath prosesor, Anda bisa mengizinkan prosesor anotasi di classpath kompilasi dengan menyetel includeCompileClasspath ke true. Akan tetapi, tidak disarankan untuk menyetel properti ini ke true, dan opsi untuk melakukannya akan dihapus pada update yang akan datang dari 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 diimport oleh aplikasi Anda). Untuk mengecualikan dependensi transitif yang sudah tidak dibutuhkan lagi, Anda bisa menggunakan kata kunci exclude seperti yang diberikan 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 ditampilkan di atas mungkin tidak berfungsi seperti yang diharapkan. Itu karena konfigurasi pengujian (mis., androidTestImplementation) memperluas konfigurasi implementation modul. Dengan kata lain, konfigurasi pengujian selalu berisi dependensi implementation saat Gradle mengatasi konfigurasi.

Jadi, untuk menngecualikan dependensi transitif dari pengujian, Anda harus melakukannya pada waktu eksekusi, seperti yang ditampilkan 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 yang 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

Android Plugin 3.0.0 dan yang lebih tinggi menyertakan mekanisme dependensi baru yang secara otomatis mencocokkan varian saat memakai library. Ini berarti varian debug aplikasi secara otomatis memakai varian debug library, dan seterusnya. Plugin ini juga berfungsi saat menggunakan ragam—sebuah varian freeDebug aplikasi akan memakai 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 tipe build yang disebut "staging", tetapi salah satu dependensi library-nya tidak demikian. Saat plugin mencoba membuat versi "staging" aplikasi, aplikasi tidak akan tahu versi library mana yang akan digunakan, dan Anda akan melihat pesan error seperti berikut:

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 cara 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 buildSolusi

Aplikasi Anda menyertakan tipe build yang tidak terdapat pada dependensi library.

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

Perhatikan, tidak ada masalah bila dependensi library menyertakan tipe build yang tidak dimiliki aplikasi Anda. Itu semata-mata karena plugin tidak pernah meminta tipe build tersebut dari dependensi.

Gunakan matchingFallbacks untuk menetapkan pencocokan alternatif bagi tipe build yang diberikan, seperti yang ditampilkan 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 dimiliki library.

Misalnya, aplikasi dan dependensi library Anda menyertakan dimensi ragam "tier". Meskipun, dimensi "tier" di aplikasi menyertakan ragam "free" dan "paid", tetapi 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 ada masalah bila library menyertakan ragam produk yang tidak dimiliki aplikasi Anda. Itu semata-mata karena plugin tidak pernah meminta ragam itu dari dependensi.

Gunakan matchingFallbacks untuk menetapkan pencocokan alternatif bagi ragam produk "free" aplikasi, seperti yang ditampilkan 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 dimiliki aplikasi Anda.

Misalnya, dependensi library menyertakan ragam untuk dimensi "minApi" , tetapi aplikasi Anda menyertakan ragam hanya untuk dimensi "tier". Jadi, ketika Anda ingin mem-build versi "freeDebug" aplikasi, plugin tidak tahu apakah akan menggunakan versi "minApi23Debug" atau "minApi18Debug" dari dependensi.

Perhatikan, tidak ada masalah bila aplikasi Anda menyertakan dimensi ragam yang tidak dimiliki oleh dependensi library. Itu karena plugin tersebut mencocokkan ragam dari dimensi yang ada dalam dependensi saja. Misalnya, jika dependensi tidak menyertakan dimensi untuk ABI, versi "freeX86Debug" aplikasi Anda hanya akan menggunakan versi "freeDebug" dari dependensi.

Gunakan missingDimensionStrategy dalam blok defaultConfig untuk menetapkan ragam default yang harus dipilih plugin dari setiap dimensi yang hilang, seperti yang ditampilkan dalam contoh di bawah ini. Anda juga bisa mengganti pilihan Anda di blok productFlavors, sehingga setiap ragam bisa 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, mereka 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 memakai varian yang cocok dengan modul Wear. Jika Anda membuat aplikasi sederhana dengan dependensi pada satu modul Wear saja, di mana modul mengonfigurasi varian yang sama sebagai modul dasar, Anda perlu menetapkan konfigurasi wearApp dalam file build.gradle modul dasar seperti yang ditampilkan 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 Anda memiliki beberapa modul Wear dan ingin menetapkan modul Wear yang berbeda per ragam aplikasi, Anda bisa melakukannya dengan menggunakan konfigurasi flavorWearApp , seperti berikut (namun, Anda tidak bisa menyertakan dependensi lain yang menggunakan konfigurasi wearApp):

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

Repositori jarak jauh

Bila dependensi Anda adalah sesuatu selain library lokal atau pohon 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 mendownload dependensi dari repositori A.

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

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

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

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

Atau Anda bisa 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 milik Google

Versi terbaru library Android berikut tersedia dari repositori Maven milik Google:

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

Untuk menambahkan salah satu library ini ke build Anda, sertakan repositori Maven milik Google di level teratas file build.gradle:

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 terlihat seperti ini:

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

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

Akses terprogram

Untuk akses terprogram ke artifak Maven milik Google, Anda bisa mendapatkan daftar XML grup artifak dari maven.google.com/master-index.xml. Kemudian, untuk grup apa saja, Anda bisa 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 milik Google (biasanya versi library yang lebih lama), Anda harus mendownload package offline Google Repository dari SDK Manager.

Kemudian Anda bisa menambahkan library ini ke blok dependencies seperti biasa.

Library offline disimpan di android_sdk/extras/.

Urutan dependensi

Urutan Anda mencantumkan dependensi menunjukkan prioritas setiap dependensi: library pertama lebih tinggi prioritasnya dari yang kedua, library kedua lebih tinggi prioritasnya dari yang ketiga, dan seterusnya. Urutan ini penting seandainya sumber daya digabungkan atau elemen manifes digabungkan ke dalam aplikasi Anda dari library.

Misalnya, jika project Anda mendeklarasikan yang berikut ini:

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

Kemudian, 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 bisa 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 project /dependensi yang berbeda digabungkan, lihat Penggabungan beberapa file manifes.

Melihat pohon dependensi

Sebagian dependensi langsung mungkin memiliki dependensi sendiri. Ini disebut dependensi transitif. Daripada mengharuskan Anda secara manual mendeklarasikan setiap dependensi transitif, Gradle secara otomatis mengumpulkan dan menambahkannya untuk Anda. Untuk memvisualisasikan dependensi langsung dan dependensi transitif project Anda, Android Plugin for Gradle menyediakan tugas Gradle yang menghasilkan sebuah pohon dependensi untuk setiap varian build dan set sumber pengujian.

Untuk menjalankan tugas, lakukan seperti berikut:

  1. Pilih View > Tool Windows > Gradle (atau klik Gradle di panel jendela fitur).
  2. Expand AppName > Tasks > android dan klik dua kali androidDependencies. Setelah Gradle mengeksekusi tugas, jendela Run akan terbuka untuk menampilkan keluarannya.

Keluaran contoh berikut menampilkan pohon dependensi untuk varian debug build, dan menyertakan dependensi modul library lokal dan dependensi jarak jauh dari contoh sebelumnya.

Executing tasks: [androidDependencies]
:app:androidDependencies
debug
/**
 * Both the library module dependency and remote binary dependency are listed
 * with their transitive dependencies.
 */
+--- MyApp:mylibrary:unspecified
|    \--- com.android.support:appcompat-v7:28.0.0
|         +--- com.android.support:animated-vector-drawable:28.0.0
|         |    \--- com.android.support:support-vector-drawable:28.0.0
|         |         \--- com.android.support:support-v4:28.0.0
|         |              \--- LOCAL: internal_impl-28.0.0.jar
|         +--- com.android.support:support-v4:28.0.0
|         |    \--- LOCAL: internal_impl-28.0.0.jar
|         \--- com.android.support:support-vector-drawable:28.0.0
|              \--- com.android.support:support-v4:28.0.0
|                   \--- LOCAL: internal_impl-28.0.0.jar
\--- com.android.support:appcompat-v7:28.0.0
     +--- com.android.support:animated-vector-drawable:28.0.0
     |    \--- com.android.support:support-vector-drawable:28.0.0
     |         \--- com.android.support:support-v4:28.0.0
     |              \--- LOCAL: internal_impl-28.0.0.jar
     +--- com.android.support:support-v4:28.0.0
     |    \--- LOCAL: internal_impl-28.0.0.jar
     \--- com.android.support:support-vector-drawable:28.0.0
          \--- com.android.support:support-v4:28.0.0
               \--- LOCAL: internal_impl-28.0.0.jar
...

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

Memperbaiki error resolusi dependensi

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

Untuk membantu Anda menyelidiki dependensi mana yang berperan pada error , periksa pohon dependensi aplikasi Anda dan cari dependensi yang muncul lebih dari sekali atau yang muncul dengan versi yang mengalami konflik.

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

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

Bagian berikut ini menjelaskan beragam tipe error resolusi dependensi yang mungkin Anda jumpai dan cara memperbaikinya.

Memperbaiki error class duplikat

Jika 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 mendeklarasikan 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 jauh pada library yang sama.
    • Untuk mengatasi masalah ini, hapus salah satu dependensi biner.

Mengatasi konflik antara classpath

Ketika Gradle mengatasi classpath kompilasi, Gradle akan mengatasi 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 di 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. Hirarki classpath dijelaskan dalam gambar 1.

Gambar 1. Nomor versi dependensi yang muncul pada beberapa classpath harus cocok sesuai dengan hirarki ini.

Jika versi yang mengalami konflik dari dependensi yang sama muncul di beberapa classpath, Anda mungkin melihat error yang serupa dengan yang berikut:

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.

Anda mungkin melihat konflik ini ketika, misalnya, aplikasi Anda menyertakan versi dependensi menggunakan implementation konfigurasi dependensi dan modul library menyertakan versi dependensi yang berbeda menggunakan konfigurasi runtimeOnly. Untuk mengatasi masalah ini, lakukan salah satu dari hal berikut:

  • Sertakan versi yang diinginkan dari dependensi 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. Pertimbangkan versi mengonfigurasi properti di seluruh project untuk memastikan setiap dependensi tetap konsisten di seluruh project Anda.

Menerapkan logika build khusus

Bagian ini menjelaskan topik-topik lanjutan yang berguna saat Anda ingin memperpanjang plugin Android Gradle atau menulis plugin Anda sendiri.

Memublikasikan varian dependensi ke logika khusus

Library dapat memiliki fungsionalitas yang mungkin ingin digunakan project atau sub project lain. Memublikasikan library adalah proses saat library yang dibuat tersedia bagi konsumennya. Library dapat mengontrol dependensi mana 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 untuk 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 tentang hubungan antara beragam konfigurasi, buka Konfigurasi plugin Java Library.

Menyesuaikan strategi resolusi dependensi

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

Untuk mengatasi konflik ini, Plugin Android Gradle menggunakan strategi resolusi dependensi berikut: ketika plugin mendeteksi bahwa versi yang berbeda dari modul yang sama ada dalam grafik dependensi, 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 resolusi dependensi, gunakan konfigurasi berikut untuk menyelesaikan dependensi spesifik dari varian yang diperlukan untuk tugas Anda:

  • variant_nameCompileClasspath: Konfigurasi ini berisi strategi resolusi untuk classpath kompilasi varian yang diberikan.
  • variant_nameRuntimeClasspath: Konfigurasi ini berisi strategi resolusi untuk classpath waktu proses varian yang diberikan.

Plugin Android Gradle menyertakan getter yang dapat Anda gunakan untuk mengakses objek konfigurasi dari setiap varian. Dengan demikian, Anda dapat menggunakan varian API untuk meminta resolusi dependensi seperti yang 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 {
            ...
        }
    }
}