tl; dr
Cukup ganti:
compile
dengan implementation
(jika Anda tidak membutuhkan transitivitas) atau api
(jika Anda memerlukan transitivitas)
testCompile
dengan testImplementation
debugCompile
dengan debugImplementation
androidTestCompile
dengan androidTestImplementation
compileOnly
masih valid Itu ditambahkan di 3.0 untuk menggantikan disediakan dan tidak dikompilasi. ( provided
diperkenalkan ketika Gradle tidak memiliki nama konfigurasi untuk use-case itu dan menamainya setelah lingkup yang disediakan Maven.)
Ini adalah salah satu perubahan besar yang datang dengan Gradle 3.0 yang diumumkan Google di IO17 .
The compile
konfigurasi sekarang usang dan harus diganti dengan implementation
atauapi
Dari dokumentasi Gradle :
dependencies {
api 'commons-httpclient:commons-httpclient:3.1'
implementation 'org.apache.commons:commons-lang3:3.5'
}
Ketergantungan yang muncul dalam api
konfigurasi akan terpapar secara transparan kepada konsumen perpustakaan, dan dengan demikian akan muncul pada kompilasi classpath konsumen.
Ketergantungan yang ditemukan dalam implementation
konfigurasi, di sisi lain, tidak akan terpapar ke konsumen, dan karenanya tidak bocor ke kompilasi classpath konsumen. Ini dilengkapi dengan beberapa manfaat:
- dependensi tidak bocor ke kompilasi classpath konsumen lagi, sehingga Anda tidak akan pernah secara tidak sengaja bergantung pada dependensi transitif
- kompilasi yang lebih cepat berkat ukuran classpath yang berkurang
- lebih sedikit kompilasi ketika dependensi implementasi berubah: konsumen tidak perlu dikompilasi ulang
- penerbitan bersih: ketika digunakan bersama dengan plugin maven-publish baru, perpustakaan Java menghasilkan file POM yang membedakan secara tepat antara apa yang diperlukan untuk dikompilasi terhadap perpustakaan dan apa yang diperlukan untuk menggunakan perpustakaan saat runtime (dengan kata lain, jangan campur apa yang dibutuhkan untuk mengkompilasi perpustakaan itu sendiri dan apa yang dibutuhkan untuk dikompilasi terhadap perpustakaan).
Konfigurasi kompilasi masih ada, tetapi tidak boleh digunakan karena tidak akan menawarkan jaminan yang disediakan oleh api
dan implementation
konfigurasi.
Catatan: jika Anda hanya menggunakan perpustakaan di modul aplikasi Anda - kasing umum - Anda tidak akan melihat perbedaan.
Anda hanya akan melihat perbedaannya jika Anda memiliki proyek yang rumit dengan modul tergantung satu sama lain, atau Anda membuat perpustakaan.
implementation
menyembunyikan ketergantungan. Apakah pertanyaan saya masuk akal?implementation
hanya menggunakan x api akan diekspos, tetapi jika Anda menggunakanapi
y, z juga akan terpapar.Jawaban ini akan menunjukkan perbedaan antara
implementation
,api
dancompile
pada sebuah proyek.Katakanlah saya punya proyek dengan tiga modul Gradle:
app
memilikimyandroidlibrary
dependensi.myandroidlibrary
memilikimyjavalibrary
dependensi.myjavalibrary
punyaMySecret
kelasmyandroidlibrary
memilikiMyAndroidComponent
kelas yang memanipulasi nilai dariMySecret
kelas.Terakhir,
app
hanya tertarik pada nilai darimyandroidlibrary
Sekarang, mari kita bicara tentang ketergantungan ...
app
perlu dikonsumsi:myandroidlibrary
, jadi dalamapp
penggunaan build.gradleimplementation
.( Catatan : Anda dapat menggunakan api / kompilasi juga. Tapi tahan pikiran itu sejenak.)
Bagaimana menurut anda
myandroidlibrary
seharusnya build.gradle? Lingkup mana yang harus kita gunakan?Kami memiliki tiga opsi:
Kompilasi atau Api (opsi # 2 atau # 3)
Jika Anda menggunakan
compile
atauapi
. Aplikasi Android kami sekarang dapat mengaksesmyandroidcomponent
ketergantungan, yang merupakanMySecret
kelas.Implementasi (opsi # 1)
Jika Anda menggunakan
implementation
konfigurasi,MySecret
tidak terbuka.Jadi, konfigurasi mana yang harus Anda pilih? Itu sangat tergantung pada kebutuhan Anda.
Jika Anda ingin mengekspos dependensi, gunakan
api
ataucompile
.Jika Anda tidak ingin mengekspos dependensi (menyembunyikan modul internal Anda) kemudian gunakan
implementation
.catatan:
Ini hanya inti dari konfigurasi Gradle, lihat Tabel 49.1. Plugin Java Library - konfigurasi yang digunakan untuk mendeklarasikan dependensi untuk penjelasan lebih rinci.
Proyek sampel untuk jawaban ini tersedia di https://github.com/aldoKelvianto/ImplementationVsCompile
sumber
compile
tidak menjamin hal yang sama yangapi
menjamin.Compile
konfigurasi sudah usang dan harus diganti olehimplementation
atauapi
.Anda dapat membaca dokumen di https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation .
Bagian singkat menjadi-
Untuk penjelasan lebih lanjut lihat gambar ini.
sumber
Solusi Singkat:
Pendekatan yang lebih baik adalah mengganti semua
compile
dependensi denganimplementation
dependensi. Dan hanya di mana Anda membocorkan antarmuka modul, Anda harus menggunakannyaapi
. Itu seharusnya menyebabkan kompilasi yang jauh lebih sedikit.Jelaskan lebih:
Sebelum Android Gradle plugin 3.0 : kami memiliki masalah besar yaitu satu perubahan kode menyebabkan semua modul dikompilasi ulang. Akar penyebabnya adalah Gradle tidak tahu apakah Anda membocorkan antarmuka modul melalui modul lain atau tidak.
Setelah Android Gradle plugin 3.0 : plugin Android Gradle terbaru sekarang mengharuskan Anda untuk secara eksplisit menentukan apakah Anda membocorkan antarmuka modul. Berdasarkan hal itu, ia dapat membuat pilihan yang tepat tentang apa yang harus dikompilasi ulang.
Dengan demikian
compile
ketergantungan telah ditinggalkan dan digantikan oleh dua yang baru:api
: Anda membocorkan antarmuka modul ini melalui antarmuka Anda sendiri, artinya sama persis dengancompile
ketergantungan lamaimplementation
: Anda hanya menggunakan modul ini secara internal dan tidak membocorkannya melalui antarmuka AndaJadi sekarang Anda dapat secara eksplisit memberi tahu Gradle untuk mengkompilasi ulang modul jika antarmuka modul yang digunakan berubah atau tidak.
Atas perkenan blog Jeroen Mols
sumber
sumber
implementation
diikuti oleh aruntime
.Perbedaan singkat dalam istilah awam adalah:
baca jawabannya oleh @aldok untuk contoh yang komprehensif.
sumber
Karena versi 5.6.3 Dokumentasi gradle memberikan aturan praktis sederhana untuk mengidentifikasi apakah
compile
ketergantungan lama (atau yang baru) harus diganti dengan ketergantunganimplementation
atauapi
:sumber
Gradle 3.0
memperkenalkan perubahan selanjutnya:compile
->api
api
kata kunci sama dengan usangcompile
compile
->implementation
Lebih disukai karena memiliki beberapa kelebihan.
implementation
mengekspos dependensi hanya untuk satu level di atas pada waktu build (dependensi tersedia saat runtime). Akibatnya Anda memiliki build yang lebih cepat (tidak perlu mengkompilasi ulang konsumen yang lebih tinggi dari 1 level ke atas)provided
->compileOnly
Ketergantungan ini hanya tersedia dalam waktu kompilasi (ketergantungan tidak tersedia saat runtime). Ketergantungan ini tidak bisa transitif dan menjadi
.aar
. Ini dapat digunakan dengan kompilasi prosesor anotasi waktu dan memungkinkan Anda untuk mengurangi file keluaran akhircompile
->annotationProcessor
Sangat mirip dengan
compileOnly
tetapi juga menjamin bahwa ketergantungan transitif tidak terlihat bagi konsumenapk
->runtimeOnly
Ketergantungan tidak tersedia dalam waktu kompilasi tetapi tersedia saat runtime.
sumber
api = public
,,implementation = internal
dancompileOnly = private
- Saya perlu membuat alias untuk fungsi-fungsi ini karena sangat membingungkan.