File build Anda menentukan dependensi direct, namun setiap dependensi tersebut dapat mewajibkan dependensi lain. Dependensi transitif ini dengan cepat menumbuhkan grafik dependensi secara keseluruhan, sering kali dengan versi yang bertentangan.
Saat bagian minor
(fitur baru) atau patch
(perbaikan bug) berubah, library
masih cenderung kompatibel dan cenderung tidak memengaruhi aplikasi Anda.
Misalnya, aplikasi Anda bergantung pada library A dan library B, yang pada akhirnya bergantung pada versi library C yang berbeda.
Dalam hal ini, Gradle memilih library C versi terbaru secara default, yang dapat menyebabkan masalah kompilasi atau runtime. Dalam contoh ini, library C di-resolve ke 2.1.1, tetapi perhatikan bahwa library A meminta library C 1.0.3. Sebagian besar nomor versi telah berubah, yang menunjukkan perubahan yang tidak kompatibel, seperti fungsi atau jenis yang dihapus. Hal ini dapat menyebabkan panggilan yang dilakukan dari library A mengalami error.
Aplikasi Anda dapat memiliki dependensi langsung yang juga merupakan dependensi transitif.
Dalam kasus seperti ini, dependensi transitif yang lebih baru dapat mengganti versi yang Anda minta secara langsung di aplikasi.
Gradle melihat semua versi kandidat untuk semua dependensi dalam grafik guna menentukan versi terbaru dari setiap dependensi. Anda dapat menggunakan tugas Gradle dasar dan alat yang lebih canggih untuk menentukan versi setiap dependensi yang telah diselesaikan Gradle. Membandingkan perubahan dalam resolusi ini adalah kunci untuk memahami dan mengurangi risiko upgrade Anda.
Misalnya, Anda dapat menggunakan tugas dependencies
Gradle dengan menjalankan ./gradlew
app:dependencies
untuk menampilkan hierarki semua dependensi yang digunakan oleh modul
aplikasi Anda. Menjalankan pengujian ini pada aplikasi yang menggunakan library seperti ditunjukkan dalam
gambar 2, kita melihat
1: releaseRuntimeClasspath - Runtime classpath of /release.
2: +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0
3: | +--- ... (omitted for brevity) ...
4: +--- com.sample:library.a:1.2.3
5: | +--- com.sample:library.c:2.1.1
6: | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
7: | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
8: +--- com.sample:library.c:1.4.1 -> 2.1.1 (*)
Bagian laporan ini menunjukkan beberapa dependensi yang di-resolve untuk
konfigurasi releaseRuntimeClasspath
.
Setiap kali Anda melihat ->
dalam laporan dependensi, pemohon (aplikasi
atau library lain) menggunakan versi dependensi tersebut yang tidak
diharapkan. Dalam banyak kasus, hal ini tidak menyebabkan masalah apa pun karena sebagian besar library
ditulis untuk kompatibilitas mundur. Namun, beberapa library mungkin membuat
perubahan yang tidak kompatibel, dan laporan ini dapat membantu Anda menentukan asal masalah
baru terkait perilaku aplikasi.
Detail selengkapnya tentang penggunaan pelaporan dependensi Gradle dapat ditemukan di Melihat dan Men-debug Dependensi.
Anda dapat menentukan versi yang diminta secara langsung, dalam katalog versi, atau dalam Bill of Materials (BOM).
Resolusi spesifikasi versi langsung
Versi dependensi yang Anda tentukan akan menjadi kandidat untuk resolusi versi.
Misalnya, untuk meminta library androidx.compose.ui:ui
versi 1.7.3 sebagai
dependensi di app/build.gradle.kts
:
dependencies {
implementation("androidx.compose.ui:ui:1.7.3")
}
Versi 1.7.3 menjadi versi kandidat. Gradle me-resolve ke versi terbaru di antara 1.7.3 dan versi lain dari library yang sama yang diminta oleh dependensi transitif.
Resolusi katalog versi
Katalog versi menentukan variabel untuk melacak versi dependensi yang digunakan di seluruh aplikasi Anda. Jika Anda menggunakan variabel dari katalog versi, dependensi yang ditentukan variabel tersebut akan ditambahkan ke kandidat untuk resolusi versi. Variabel yang tidak digunakan dalam katalog versi akan diabaikan.
Misalnya, untuk menentukan versi 1.7.3 androidx.compose.ui:ui
sebagai
dependensi dalam file gradle/libs.versions.toml
Anda:
[versions]
ui = "1.7.3"
[libraries]
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "ui" }
Tindakan ini menentukan variabel bernama libs.androidx.compose.ui
untuk mewakili
library. Versi ini tidak dianggap sebagai kandidat kecuali jika Anda menggunakan variabel tersebut untuk menentukan dependensi.
Untuk meminta library dan versinya di app/build.gradle.kts
:
dependencies {
implementation(libs.androidx.compose.ui)
}
Gradle me-resolve dengan cara yang sama seperti untuk spesifikasi langsung.
Resolusi Bill of Materials (BOM)
Versi untuk semua library yang muncul di BOM menjadi kandidat untuk resolusi versi. Perhatikan bahwa library hanya digunakan sebagai dependensi jika ditentukan sebagai langsung atau tidak langsung. Library lain di BOM akan diabaikan.
Versi BOM memengaruhi dependensi langsung Anda serta semua dependensi transitif yang muncul dalam BOM.
Misalnya, tentukan BOM sebagai dependensi platform di
app/build.gradle.kts
Anda:
dependencies {
implementation(platform("androidx.compose:compose-bom:2024.10.00"))
implementation("androidx.compose.ui:ui")
}
Setiap library yang ingin Anda gunakan sebagai dependensi tidak memerlukan spesifikasi versi; versi yang diminta berasal dari BOM.
Perlu diperhatikan bahwa Anda juga dapat menggunakan katalog versi untuk membuat variabel bagi BOM dan library. Hapus nomor versi dalam katalog versi untuk library yang muncul dalam dependensi BOM.
Misalnya, katalog versi Anda berisi BOM dan nomor versinya, tetapi tidak menentukan versi untuk library yang Anda referensikan dari BOM:
[versions]
composeBom = "2024.10.00"
[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
app/build.gradle.kts
Anda mereferensikan BOM dan library menggunakan variabel
yang ditentukan dalam katalog versi:
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
}
Versi library yang ditentukan dalam BOM menjadi kandidat untuk resolusi Gradle. Selain itu, semua versi library lain yang ditentukan dalam BOM menjadi versi kandidat, terlepas dari apakah Anda menggunakannya secara langsung sebagai dependensi atau tidak.
Misalnya, BOM menentukan versi untuk library A, B, dan C. Aplikasi Anda ingin langsung menggunakan library A sebagai dependensi, serta library D. Library D menggunakan library B sebagai dependensi. Tidak ada yang menggunakan library C.
Library A, B, dan D adalah dependensi dalam aplikasi; library C diabaikan. Gradle menggunakan versi A dan B yang ditentukan dalam BOM sebagai kandidat, meskipun Anda tidak secara langsung menetapkan library B sebagai dependensi.
Jika library D meminta versi library B yang lebih rendah dari 2.0.1, Gradle akan me-resolve ke 2.0.1. Jika library D meminta versi library B yang lebih tinggi, Gradle akan me-resolve ke versi tersebut.