Saat menambahkan dependensi, Anda mungkin mengalami masalah dengan dependensi yang diperlukan oleh dependensi asli, dan konflik di antara berbagai versi dependensi. Berikut ini cara menganalisis grafik dependensi dan memperbaiki masalah umum yang muncul.
Untuk panduan tentang cara memperbaiki error resolusi dependensi yang melibatkan build kustom logika, lihat Strategi resolusi dependensi kustom.
Menampilkan dependensi modul
Sebagian dependensi langsung mungkin memiliki dependensi sendiri. Dependensi semacam ini disebut dependensi transitif. Gradle mengumpulkan dan menambahkannya secara otomatis sehingga Anda tidak harus mendeklarasikan setiap dependensi transitif secara manual. Plugin Android untuk Gradle 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 laporan contoh untuk classpath runtime modul aplikasi dari varian build debug dan classpath kompilasi 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 ini, lakukan langkah berikut:
- Pilih View > Tool Windows > Gradle (atau klik Gradle di kolom jendela alat).
- Perluas AppName > 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 pengelolaan dependensi di Panduan Pengguna Gradle.
Mengecualikan dependensi transitif
Seiring bertambahnya cakupan aplikasi, aplikasi dapat berisi sejumlah dependensi, termasuk dependensi langsung dan dependensi transitif (library yang digunakan oleh library yang diimpor milik aplikasi Anda).
Untuk mengecualikan dependensi transitif yang sudah tidak dibutuhkan lagi, Anda dapat menggunakan kata kunci
exclude
seperti yang di bawah ini:
Kotlin
dependencies { implementation("some-library") { exclude(group = "com.example.imgtools", module = "native") } }
Groovy
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 ini dikarenakan konfigurasi pengujian (misalnya androidTestImplementation
) akan memperluas konfigurasi implementation
modul. Dengan kata lain, 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:
Kotlin
android.testVariants.all { compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") }
Groovy
android.testVariants.all { variant -> variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' }
Catatan: Anda tetap dapat menggunakan kata kunci exclude
di blok dependensi seperti yang ditunjukkan dalam contoh kode asli dari bagian
Mengecualikan dependensi transitif untuk menghilangkan
dependensi transitif yang khusus untuk konfigurasi pengujian
dan tidak termasuk dalam konfigurasi lain.
Memperbaiki error penyelesaian dependensi
Jika Anda menambahkan beberapa dependensi ke project aplikasi Anda, dependensi langsung dan transitif tersebut mungkin berkonflik satu sama lain. Plugin Android Gradle mencoba me-resolve konflik ini tanpa hambatan, tetapi beberapa konflik dapat menyebabkan error waktu kompilasi atau error runtime.
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 mengalami konflik.
Jika Anda kesulitan mengenali dependensi duplikat, cobalah menggunakan UI Android Studio untuk menelusuri dependensi yang menyertakan class duplikat seperti berikut:
- Pilih Navigate > Class dari panel menu.
- Dalam dialog penelusuran pop-up, pastikan kotak di samping Include non-project items dicentang.
- Ketikkan nama class yang muncul dalam error build.
- Periksa hasilnya untuk menemukan 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 runtime, Anda akan mendapat error yang terlihat seperti 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 jarak jauh pada library yang sama.
- Untuk mengatasi masalah ini, hapus salah satu dependensi biner.
Mengatasi konflik antar-classpath
Saat menangani classpath kompilasi, Gradle akan menangani classpath runtime terlebih dahulu dan menggunakan hasilnya untuk menentukan versi dependensi yang harus ditambahkan ke classpath kompilasi. Dengan kata lain, classpath runtime menentukan nomor versi yang diperlukan untuk dependensi identik pada classpath downstream.
Classpath runtime aplikasi Anda juga menentukan nomor versi yang diperlukan Gradle untuk mencocokkan dependensi dalam classpath runtime bagi APK pengujian aplikasi. Hierarki classpath dijelaskan dalam gambar 1.
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 runtime dan classpath waktu kompilasi, plugin Android Gradle 3.3.0 dan yang lebih tinggi mencoba untuk memperbaiki konflik versi downstream tertentu secara otomatis. Misalnya, jika classpath runtime menyertakan Library A versi 2.0 dan classpath kompilasi menyertakan Library A versi 1.0, plugin akan otomatis memperbarui dependensi pada classpath kompilasi ke Library A versi 2.0 untuk menghindari error.
Namun, jika classpath runtime 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 seperti 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 langkah berikut:
- Sertakan versi dependensi yang diinginkan dari dependensi sebagai dependensi
api
ke modul library Anda. Artinya, hanya modul library Anda yang mendeklarasikan dependensi, tetapi secara transitif, modul aplikasi juga akan memiliki akses ke API-nya. - Atau, Anda dapat mendeklarasikan dependensi pada kedua modul, tetapi Anda harus memastikan bahwa setiap modul menggunakan versi dependensi yang sama. Sebaiknya konfigurasikan properti skala project untuk memastikan konsistensi versi setiap dependensi di seluruh project Anda.