Coil — adalah pustaka untuk memuat gambar di Android, ditulis dalam Kotlin dan dibangun di atas coroutine. Menurut dokumentasi resmi, pustaka ini mendukung Memory Cache, Disk Cache dan transformasi dengan akselerasi perangkat keras. Coil menonjol dengan ukuran APK minimal (sekitar 150 KB) dan kompatibilitas penuh dengan Jetpack Compose.
Poin utama
Coil (Coroutine Image Loader) — adalah pustaka untuk memuat gambar di Android, sepenuhnya ditulis dalam Kotlin dan menggunakan coroutine untuk kerja asinkron. Ia menyediakan API terpadu untuk memuat gambar bitmap dari jaringan, sumber daya, sistem file, dan Content Provider, dengan caching otomatis di beberapa tingkat.
Tidak seperti Glide dan Picasso, Coil menggunakan Kotlin Coroutines alih-alih rantai callback, membuat kode lebih linier dan dapat diprediksi. Semua operasi pemuatan dan pendekodean dilakukan di thread latar belakang melalui Dispatchers.IO, dan hasilnya dikirim ke thread utama tanpa perpindahan eksplisit.
Coil mendukung transformasi (Round, Blur, Grayscale), animasi transisi, SVG dan GIF, serta Target kustom untuk tampilan non-standar. Menurut Google I/O 2023, Coil direkomendasikan dalam tutorial resmi Jetpack Compose bersama dengan Glide.
ImageLoader — komponen utama Coil yang bertanggung jawab untuk menjalankan permintaan pemuatan dan mengelola cache. Setiap instance berisi referensi ke MemoryCache, DiskCache, BitmapPool dan kumpulan coroutine. Secara default digunakan singleton yang dibuat melalui Coil.imageLoader(context).
ImageRequest — objek yang menggambarkan satu permintaan pemuatan gambar: sumber data (URL, URI, sumber Int), ImageView atau Target tujuan, transformasi, pengaturan caching dan placeholder. ImageRequest dibangun melalui builder, yang memberikan fleksibilitas dan keterbacaan.
val request = ImageRequest.Builder(context)
.data("https://example.com/image.jpg")
.crossfade(true)
.size(512, 512)
.transformations(listOf(RoundedCornersTransformation(12f)))
.memoryCachePolicy(CachePolicy.ENABLED)
.diskCachePolicy(CachePolicy.ENABLED)
.target(imageView)
.build()
Setelah dibangun, ImageRequest diteruskan ke ImageLoader melalui enqueue atau execute. Metode enqueue menjalankan coroutine dan mengembalikan Disposable, memungkinkan pembatalan pemuatan saat meninggalkan layar. Metode execute adalah fungsi suspend yang mengembalikan Result secara langsung.
ImageLoader secara berurutan memeriksa MemoryCache, DiskCache dan hanya jika keduanya tidak ditemukan, menjalankan permintaan jaringan melalui HttpEngine. Setelah dimuat, byte didekode menjadi Bitmap dengan mempertimbangkan ukuran target, transformasi diterapkan, hasilnya disimpan di kedua cache dan diteruskan ke Target.
Coil dibangun di atas arsitektur komponen dengan kemampuan mengganti bagian mana pun melalui Dependency Injection. Semua komponen didaftarkan di ImageLoaderFactory dan diteruskan ke konstruktor ImageLoader melalui builder.
ImageLoader — titik masuk untuk semua operasi pemuatan. Setiap instance berisi kumpulan coroutine, BitmapPool, MemoryCache, DiskCache dan daftar interceptor. Secara default dibuat satu instance global, tetapi untuk pengujian modular dapat dibuat instance terpisah dengan cache terisolasi.
MemoryCache — cache dalam memori berbasis LRU (Least Recently Used) yang menyimpan objek Bitmap yang telah didekode. Ukuran maksimum default adalah 25% dari memori aplikasi yang tersedia, tetapi tidak kurang dari 32 MB. Kunci cache dibentuk dari URL + ukuran + transformasi, yang mengecualikan pemberian gambar yang tidak relevan.
DiskCache — cache file untuk data mentah (JPEG, PNG, WebP) dan metadata yang telah didekode. Terletak di direktori cache aplikasi dan mendukung pembersihan otomatis saat melebihi batas. Pekerjaan dengan disk dilakukan melalui DiskCache.Builder dengan pengaturan direktori dan ukuran maksimum.
Coil mengimplementasikan strategi caching bertingkat yang meminimalkan permintaan jaringan dan mempercepat tampilan gambar. Setiap tingkat memiliki tujuan dan masa pakai data sendiri.
| Tingkat | Jenis penyimpanan | Masa pakai | Ukuran default |
|---|---|---|---|
| Memory Cache | Bitmap di memori | Hingga penggantian LRU | 25% heap, dari 32 MB |
| Disk Cache | File JPEG/WebP | Hingga melebihi batas | 250 MB |
| Http Cache | Respons OkHttp | Berdasarkan header Cache-Control | Tergantung klien HTTP |
Memory Cache menyediakan akses instan ke bitmap yang sudah didekode. Disk Cache menjamin aplikasi bekerja tanpa jaringan (offline-first) setelah pemuatan pertama. Http Cache di tingkat OkHttp memproses permintaan bersyarat ETag dan If-Modified-Since.
Kebijakan caching dikonfigurasi per-permintaan melalui CachePolicy dengan tiga nilai: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Misalnya, untuk avatar pengguna dapat diatur READ_ONLY untuk Memory Cache dan ENABLED untuk Disk Cache.
Coil menawarkan beberapa metode integrasi tergantung pada arsitektur aplikasi. Mari kita lihat tiga skenario utama dengan contoh kode yang berfungsi.
load — fungsi ekstensi untuk ImageView, cara termudah untuk memuat gambar dalam satu baris. Fungsi ini menerima URL, URI, sumber Int atau File dan semua parameter opsional melalui konfigurator lambda.
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
Metode load mengembalikan Disposable yang dapat dibatalkan di onDestroy atau saat penggunaan ulang View. Ini mencegah kebocoran memori dan permintaan jaringan yang tidak perlu saat scrolling cepat daftar.
AsyncImage — fungsi composable untuk memuat gambar di UI deklaratif. Menerima sumber data apa pun dan tiga parameter opsional untuk status: placeholder, error dan success.
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "gambar jaringan",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage — versi yang lebih fleksibel yang memungkinkan penyesuaian tampilan selama pemuatan melalui slot konten. Ini berguna untuk skeleton (shimmer) dan bilah kemajuan.
Jika ImageView atau AsyncImage tidak cocok, dapat diimplementasikan Target dengan metode tunggal onSuccess yang menerima Bitmap. Ini digunakan untuk memuat ke Notification, RemoteViews atau tekstur OpenGL.
val target = object : BitmapTarget() {
override fun onSuccess(result: Bitmap) {
notificationRemoteView.setImageViewBitmap(R.id.icon, result)
}
}
imageLoader.enqueue(
ImageRequest.Builder(context)
.data(url)
.target(target)
.build()
)
Pemilihan pustaka pemuatan gambar tergantung pada kebutuhan proyek. Coil bersaing dengan Glide dan Picasso, yang masing-masing memiliki kelebihan. Perbandingan karakteristik utama disajikan dalam tabel.
| Karakteristik | Coil | Glide | Picasso |
|---|---|---|---|
| Bahasa | Kotlin (100%) | Java + Kotlin | Java |
| Ukuran APK | ~150 KB | ~500 KB | ~120 KB |
| Coroutine | Bawaan | Tidak (callback) | Tidak (callback) |
| Jetpack Compose | Dukungan asli | Melalui Accompaniment | Pihak ketiga |
| GIF/WebP | Ya (bawaan) | Ya (bawaan) | Tidak |
| Rekomendasi Google | Ya (I/O 2023) | Ya | Tidak |
Untuk proyek baru di Kotlin dan Jetpack Compose, Coil menjadi pilihan alami berkat ketergantungan nol tambahan pada coroutine dan ukuran minimal. Glide tetap lebih disukai untuk skenario kompleks dengan animasi dan pratinjau video. Picasso kalah dari keduanya dalam fungsionalitas, tetapi unggul dalam kesederhanaan.
Menghubungkan Coil ke proyek Android dilakukan melalui ketergantungan Gradle. Setelah ditambahkan, pustaka secara otomatis mendaftarkan ImageLoader melalui ContentProvider, sehingga inisialisasi manual di Application tidak diperlukan. Jika perlu penyesuaian, ImageLoader sendiri dibuat melalui builder.
// build.gradle.kts (modul aplikasi)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Tambahan untuk Jetpack Compose:
implementation("io.coil-kt:coil-compose:2.6.0")
// Untuk dukungan SVG:
implementation("io.coil-kt:coil-svg:2.6.0")
// Untuk dukungan GIF:
implementation("io.coil-kt:coil-gif:2.6.0")
}
Untuk menyesuaikan ImageLoader digunakan ImageLoaderFactory — singleton yang dibuat di Application.onCreate. Di pabrik dapat dikonfigurasi batas cache, klien HTTP, dekoder kustom dan pencatatan. Secara default Coil menggunakan OkHttp dengan kumpulan koneksi siap pakai.
class App : Application(), ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.memoryCache {
MemoryCache.Builder()
.maxSizePercent(0.25)
.build()
}
.diskCache {
DiskCache.Builder()
.directory(cacheDir.resolve("coil_cache"))
.maxSizeBytes(512 * 1024 * 1024)
.build()
}
.build()
}
}
Pertanyaan yang sering diajukan
Coil — pustaka untuk memuat gambar di Android, ditulis dalam Kotlin menggunakan coroutine. Digunakan untuk memuat, menyimpan cache, dan menampilkan gambar bitmap secara asinkron dari jaringan, sumber daya atau sistem file.
Coil ditulis 100% dalam Kotlin dan menggunakan coroutine alih-alih mekanisme callback di Glide. Coil memiliki ukuran APK lebih kecil (~150 KB vs ~500 KB) dan dukungan asli untuk Jetpack Compose melalui AsyncImage.
Tambahkan ketergantungan io.coil-kt:coil:2.6.0 di build.gradle.kts. Untuk Jetpack Compose tambahkan juga io.coil-kt:coil-compose:2.6.0. Pustaka secara otomatis mendaftarkan ImageLoader melalui ContentProvider.
Coil mendukung JPEG, PNG, WebP, BMP, SVG (melalui modul coil-svg) dan GIF (melalui modul coil-gif). Format AVIF dan HEIF didukung melalui dekoder kustom pada perangkat dengan Android 10+.
Cache dikonfigurasi melalui ImageLoader.Builder: memoryCache dengan menentukan persentase heap, diskCache dengan jalur dan batas dalam byte. Kebijakan cache (ENABLED, DISABLED, READ_ONLY) dikonfigurasi per-permintaan melalui CachePolicy.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga