Saya mencoba mencari tahu apa perbedaan antara api
dan implementation
konfigurasi saat membangun dependensi saya.
Dalam dokumentasinya, dikatakan bahwa itu implementation
memiliki waktu pembuatan yang lebih baik, tetapi, melihat komentar ini di pertanyaan serupa saya bertanya-tanya apakah itu benar.
Karena saya bukan ahli gradle, saya harap ada yang bisa membantu. Saya sudah membaca dokumentasinya tetapi saya bertanya-tanya tentang penjelasan yang mudah dipahami.
android
gradle
dependencies
implementation
reinaldomoreira
sumber
sumber
compile
menjadiapi
. Pustaka yang Anda gunakan secara internal dapat menggunakan beberapa implementasi pribadi yang tidak diekspos di pustaka akhir sehingga transparan bagi Anda. Dependensi "internal-private" tersebut dapat dialihkan keimplementation
dan saat plugin gradle Android akan mengompilasi aplikasi Anda, kompilasi dependensi tersebut akan dilewati sehingga menghasilkan waktu build yang lebih singkat (tetapi dependensi tersebut akan tersedia pada waktu proses). Jelas Anda dapat melakukan hal yang sama jika Anda memiliki perpustakaan modul lokalJawaban:
Kata
compile
kunci Gradle tidak lagi digunakan karena kata kunciapi
danimplementation
untuk mengonfigurasi dependensi.Menggunakan
api
sama dengan menggunakan deprecatedcompile
, jadi jika Anda mengganti semuacompile
denganapi
semuanya akan berfungsi seperti biasa.Untuk memahami
implementation
kata kunci, pertimbangkan contoh berikut.CONTOH
Misalkan Anda memiliki perpustakaan yang dipanggil
MyLibrary
yang secara internal menggunakan perpustakaan lain yang disebutInternalLibrary
. Sesuatu seperti ini:// 'InternalLibrary' module public class InternalLibrary { public static String giveMeAString(){ return "hello"; } }
// 'MyLibrary' module public class MyLibrary { public String myString(){ return InternalLibrary.giveMeAString(); } }
Misalkan
MyLibrary
build.gradle
menggunakanapi
konfigurasidependencies{}
seperti ini:dependencies { api project(':InternalLibrary') }
Anda ingin menggunakan
MyLibrary
dalam kode Anda sehingga di aplikasibuild.gradle
Anda , Anda menambahkan ketergantungan ini:dependencies { implementation project(':MyLibrary') }
Menggunakan
api
konfigurasi (atau tidak digunakan lagicompile
) yang dapat Anda aksesInternalLibrary
di kode aplikasi Anda:// Access 'MyLibrary' (granted) MyLibrary myLib = new MyLibrary(); System.out.println(myLib.myString()); // Can ALSO access the internal library too (but you shouldn't) System.out.println(InternalLibrary.giveMeAString());
Dengan cara ini modul
MyLibrary
berpotensi "membocorkan" implementasi internal sesuatu. Anda tidak boleh (dapat) menggunakannya karena tidak langsung diimpor oleh Anda.The
implementation
konfigurasi diperkenalkan untuk mencegah hal ini. Jadi sekarang jika Anda menggunakanimplementation
alih-alihapi
diMyLibrary
:dependencies { implementation project(':InternalLibrary') }
Anda tidak akan dapat memanggil
InternalLibrary.giveMeAString()
kode aplikasi Anda lagi.Strategi tinju semacam ini memungkinkan plugin Android Gradle mengetahui bahwa jika Anda mengedit sesuatu
InternalLibrary
, plugin tersebut hanya boleh memicu kompilasi ulangMyLibrary
dan bukan kompilasi ulang seluruh aplikasi Anda, karena Anda tidak memiliki akses keInternalLibrary
.Jika Anda memiliki banyak dependensi bersarang, mekanisme ini dapat mempercepat proses build. (Tonton video yang ditautkan di bagian akhir untuk pemahaman penuh tentang ini)
KESIMPULAN
Saat Anda beralih ke plugin Android Gradle 3.XX baru, Anda harus mengganti semua Anda
compile
denganimplementation
kata kunci * (1 ) . Kemudian coba kompilasi dan uji aplikasi Anda. Jika semuanya tidak apa-apa biarkan kodenya apa adanya, jika Anda memiliki masalah, Anda mungkin memiliki sesuatu yang salah dengan dependensi Anda atau Anda menggunakan sesuatu yang sekarang bersifat pribadi dan tidak lebih mudah diakses. * Saran oleh insinyur plugin Android Gradle Jerome Dochez (1 ) )Jika Anda adalah mantainer library, Anda harus menggunakan
api
untuk setiap dependensi yang diperlukan untuk API publik library Anda, sementara digunakanimplementation
untuk uji dependensi atau dependensi yang tidak boleh digunakan oleh pengguna akhir.Artikel yang berguna Menampilkan perbedaan antara implementasi dan api
REFERENSI (Ini adalah video yang sama yang dipisahkan untuk menghemat waktu)
Google I / O 2017 - Bagaimana mempercepat pembangunan Gradle (VIDEO LENGKAP)
Google I / O 2017 - Cara mempercepat pembuatan Gradle (NEW GRADLE PLUGIN 3.0.0 PART ONLY)
Google I / O 2017 - Cara mempercepat build Gradle (referensi ke 1 *)
Dokumentasi Android
sumber
MyLibrary#myString()
akan mogok karena ProGuard telahInternalLibrary
dihapus. Apa praktik terbaik untuk android-libs yang akan digunakan dalam aplikasi ProGuard?Saya suka memikirkan tentang
api
ketergantungan sebagai publik (dilihat oleh modul lain) sedangkanimplementation
ketergantungan sebagai pribadi (hanya dilihat oleh modul ini).Perhatikan, tidak seperti
public
/private
variabel dan metode,api
/implementation
dependensi tidak diberlakukan oleh runtime. Ini hanyalah pengoptimalan waktu build, yang memungkinkanGradle
untuk mengetahui modul mana yang perlu dikompilasi ulang ketika salah satu dependensi mengubah API-nya.sumber
api
dependensi dalam lingkup "kompilasi" (mereka akan dimasukkan sebagai dependensi di pustaka Anda dan apa pun yang bergantung pada pustaka Anda) danimplementation
dependensi dalam cakupan "runtime" (sebaiknya di classpath saat kode Anda dijalankan, tetapi tidak diperlukan untuk mengompilasi kode lain yang menggunakan library Anda).implementation
dependensi apa pun yang diperlukan untuk dijalankan (dan untuk library Anda untuk dikompilasi), tetapi itu tidak boleh ditarik secara otomatis ke dalam project yang menggunakan library Anda. Contohnya adalah jax-rs, perpustakaan Anda mungkin menggunakan RESTeasy, tetapi seharusnya tidak menarik libs tersebut ke dalam proyek apa pun yang menggunakan perpustakaan Anda, karena mereka mungkin ingin menggunakan Jersey sebagai gantinya.Anggap Anda memiliki
app
modul yang digunakanlib1
sebagai perpustakaan danlib1
digunakanlib2
sebagai perpustakaan. Sesuatu seperti ini:app -> lib1 -> lib2
.Sekarang saat menggunakan
api lib2
inlib1
, makaapp
dapat melihatlib2
kode saat menggunakan:api lib1
atauimplementation lib1
diapp
modul.TAPI ketika menggunakan
implementation lib2
dilib1
, makaapp
tidak bisa melihat denganlib2
kode.sumber
Jawaban dari @matpag dan @ dev-bmax cukup jelas untuk membuat orang memahami perbedaan penggunaan antara implementasi dan api. Saya hanya ingin membuat penjelasan ekstra dari sudut lain, berharap dapat membantu orang-orang yang memiliki pertanyaan yang sama.
Saya membuat dua proyek untuk pengujian:
Hierarki dependensi yang dijelaskan di atas terlihat seperti:
[proyek-b] -> [proyek-a] -> [spring-boot-gradle-plugin]
Kemudian saya menguji skenario berikut:
Buat proyek A bergantung pada 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' dengan implementasi .
Jalankan
gradle dependencies
perintah di terminal di direktori root B poject, dengan tangkapan layar berikut dari keluaran, kita dapat melihat bahwa 'spring-boot-gradle-plugin' muncul di pohon dependensi runtimeClasspath, tetapi tidak di compileClasspath's, saya pikir itulah mengapa kita tidak bisa membuatnya penggunaan library yang dideklarasikan menggunakan implementasi, hanya saja tidak melalui kompilasi.Buat proyek A bergantung pada 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' oleh api
Jalankan
gradle dependencies
perintah di terminal di poject B root dir lagi. Sekarang 'spring-boot-gradle-plugin' muncul di pohon dependensi compileClasspath dan runtimeClasspath.Perbedaan signifikan yang saya perhatikan adalah bahwa ketergantungan dalam proyek produser / perpustakaan yang dideklarasikan dalam cara implementasi tidak akan muncul di compileClasspath proyek konsumen, sehingga kami tidak dapat menggunakan lib yang sesuai dalam proyek konsumen.
sumber
Dari dokumentasi gradle :
Mari kita lihat skrip build yang sangat sederhana untuk proyek berbasis JVM.
plugins { id 'java-library' } repositories { mavenCentral() } dependencies { implementation 'org.hibernate:hibernate-core:3.6.7.Final' api 'com.google.guava:guava:23.0' testImplementation 'junit:junit:4.+' }
sumber