Coil, Kotlin ile yazılmış ve coroutine'ler üzerine inşa edilmiş, Android için bir görsel yükleme kütüphanesidir. Resmi dokümantasyona göre kütüphane, Memory Cache, Disk Cache ve donanım hızlandırmalı dönüşümleri destekler. Coil, minimum APK boyutu (yaklaşık 150 KB) ve Jetpack Compose ile tam uyumluluğu ile öne çıkar.
Önemli Noktalar
Coil (Coroutine Image Loader), tamamen Kotlin ile yazılmış ve asenkron işlemler için coroutine'ler kullanan Android için bir görsel yükleme kütüphanesidir. Ağ, kaynaklar, dosya sistemi ve Content Provider'dan bitmap görsellerini yüklemek için otomatik çok seviyeli önbellekleme ile birleşik bir API sağlar.
Glide ve Picasso'nun aksine Coil, geri arama zincirleri yerine Kotlin Coroutines kullanarak kodu daha doğrusal ve öngörülebilir hale getirir. Tüm yükleme ve kod çözme işlemleri, Dispatchers.IO dağıtıcısı aracılığıyla arka plan iş parçacıklarında yürütülür ve sonuçlar açık bir değiştirme olmadan ana iş parçacığına iletilir.
Coil, dönüşümleri (Round, Blur, Grayscale), geçiş animasyonlarını, SVG ve GIF'in yanı sıra standart olmayan görüntüleme için özel Target'leri destekler. Google I/O 2023'e göre Coil, Glide ile birlikte resmi Jetpack Compose eğitimlerinde önerilmektedir.
ImageLoader, Coil'in ana bileşenidir, yükleme isteklerini yürütmekten ve önbelleği yönetmekten sorumludur. Her örnek, MemoryCache, DiskCache, BitmapPool ve bir coroutine havuzuna referanslar içerir. Varsayılan olarak, Coil.imageLoader(context) aracılığıyla oluşturulan bir singleton kullanılır.
ImageRequest, tek bir görsel yükleme isteğini tanımlayan bir nesnedir: veri kaynağı (URL, URI, Int kaynağı), hedef ImageView veya Target, dönüşümler, önbellek ayarları ve yer tutucu. ImageRequest bir builder aracılığıyla oluşturulur ve esneklik ve okunabilirlik sağlar.
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()
Oluşturulduktan sonra ImageRequest, enqueue veya execute aracılığıyla ImageLoader'a iletilir. enqueue yöntemi bir coroutine başlatır ve ekrandan ayrılırken yüklemeyi iptal etmeye izin veren bir Disposable döndürür. execute yöntemi, doğrudan bir Result döndüren bir askıya alma işlevidir.
ImageLoader sırayla MemoryCache, DiskCache'i kontrol eder ve yalnızca her ikisinde de bulunamazsa HttpEngine aracılığıyla bir ağ isteği yürütür. Yüklemeden sonra, baytlar hedef boyut dikkate alınarak Bitmap'e kodlanır, dönüşümler uygulanır, sonuç her iki önbellekte saklanır ve Target'e iletilir.
Coil, Bağımlılık Enjeksiyonu aracılığıyla herhangi bir parçanın değiştirilebildiği bir bileşen mimarisi üzerine inşa edilmiştir. Tüm bileşenler ImageLoaderFactory'ye kaydedilir ve builder aracılığıyla ImageLoader yapıcısına iletilir.
ImageLoader, tüm yükleme işlemleri için giriş noktasıdır. Her örnek bir coroutine havuzu, BitmapPool, MemoryCache, DiskCache ve bir engelleyiciler listesi içerir. Varsayılan olarak bir genel örnek oluşturulur, ancak birim testleri için izole önbelleklere sahip ayrı örnekler oluşturulabilir.
MemoryCache, kodlanmış Bitmap nesnelerini depolayan LRU (Least Recently Used) tabanlı bir bellek içi önbellektir. Varsayılan maksimum boyut, kullanılabilir uygulama belleğinin %25'idir, ancak 32 MB'tan az değildir. Önbellek anahtarı URL + boyut + dönüşümlerden oluşturulur ve güncel olmayan görsel alımını önler.
DiskCache, ham veriler (JPEG, PNG, WebP) ve kodlanmış meta veriler için dosya tabanlı bir önbellektir. Uygulamanın önbellek dizininde bulunur ve sınır aşıldığında otomatik temizlemeyi destekler. Disk işlemleri, dizin ve maksimum boyut yapılandırmasıyla DiskCache.Builder aracılığıyla gerçekleştirilir.
Coil, ağ isteklerini en aza indiren ve görsel görüntülemeyi hızlandıran çok seviyeli bir önbellekleme stratejisi uygular. Her seviyenin kendi amacı ve veri ömrü vardır.
| Seviye | Depolama Türü | Ömür | Varsayılan Boyut |
|---|---|---|---|
| Memory Cache | RAM'de Bitmap | LRU çıkarılmasına kadar | Heap'in %25'i, 32 MB'tan |
| Disk Cache | JPEG/WebP dosyaları | Sınır aşılana kadar | 250 MB |
| Http Cache | OkHttp yanıtları | Cache-Control başlıklarına göre | HTTP istemcisine bağlı |
Memory Cache, zaten kodlanmış Bitmap'lere anında erişim sağlar. Disk Cache, ilk yüklemeden sonra uygulamanın ağ olmadan (çevrimdışı öncelikli) çalışmasını sağlar. OkHttp düzeyindeki Http Cache, ETag ve If-Modified-Since ile koşullu istekleri işler.
Önbellek politikaları, CachePolicy aracılığıyla istek başına üç değerle yapılandırılır: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Örneğin, kullanıcı avatarları için Memory Cache için READ_ONLY ve Disk Cache için ENABLED ayarlanabilir.
Coil, uygulama mimarisine bağlı olarak çeşitli entegrasyon yöntemleri sunar. Çalışan kod örnekleriyle üç temel senaryoyu inceleyelim.
load, ImageView için bir uzantı işlevidir, bir görseli tek satırda yüklemenin en basit yoludur. İşlev, bir lambda yapılandırıcısı aracılığıyla tüm isteğe bağlı parametrelerle birlikte URL, URI, Int kaynağı veya Dosyayı kabul eder.
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
load yöntemi, onDestroy'da veya View yeniden kullanılırken iptal edilebilen bir Disposable döndürür. Bu, hızlı liste kaydırma sırasında bellek sızıntılarını ve gereksiz ağ isteklerini önler.
AsyncImage, bildirimsel UI'da görsel yüklemek için bir composable işlevidir. Herhangi bir veri kaynağını ve durumlar için üç isteğe bağlı parametreyi kabul eder: placeholder, error ve success.
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "ağ görseli",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage, bir içerik yuvası aracılığıyla yükleme sırasında görüntülemeyi özelleştirmeye izin veren daha esnek bir sürümdür. Bu, iskeletler (shimmer) ve ilerleme çubukları için kullanışlıdır.
ImageView veya AsyncImage uygun değilse, Bitmap kabul eden tek bir onSuccess yöntemiyle bir Target uygulayabilirsiniz. Bu, Notification, RemoteViews veya OpenGL dokularına yüklemek için kullanılır.
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()
)
Görsel yükleme kütüphanesi seçimi proje gereksinimlerine bağlıdır. Coil, her biri kendi güçlü yönlerine sahip olan Glide ve Picasso ile rekabet eder. Temel özelliklerin bir karşılaştırması tabloda sunulmuştur.
| Özellik | Coil | Glide | Picasso |
|---|---|---|---|
| Dil | Kotlin (%100) | Java + Kotlin | Java |
| APK Boyutu | ~150 KB | ~500 KB | ~120 KB |
| Coroutine'ler | Dahili | Hayır (geri arama) | Hayır (geri arama) |
| Jetpack Compose | Yerel destek | accompanist aracılığıyla | Üçüncü taraf |
| GIF/WebP | Evet (dahili) | Evet (dahili) | Hayır |
| Google Tavsiyesi | Evet (I/O 2023) | Evet | Hayır |
Kotlin ve Jetpack Compose'daki yeni projeler için Coil, sıfır ek coroutine bağımlılığı ve minimum boyut sayesinde doğal seçim haline gelir. Glide, animasyonlar ve video önizlemeleri içeren karmaşık senaryolar için tercih edilmeye devam etmektedir. Picasso, işlevsellik açısından her ikisinin de gerisinde kalır ancak basitlikte kazanır.
Coil'in bir Android projesine eklenmesi bir Gradle bağımlılığı aracılığıyla yapılır. Eklendikten sonra kütüphane, ContentProvider aracılığıyla otomatik olarak bir ImageLoader kaydeder, bu nedenle Application'da manuel başlatma gerekmez. Özelleştirme gerekiyorsa, builder aracılığıyla özel bir ImageLoader oluşturulur.
// build.gradle.kts (app module)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Jetpack Compose için ek olarak:
implementation("io.coil-kt:coil-compose:2.6.0")
// SVG desteği için:
implementation("io.coil-kt:coil-svg:2.6.0")
// GIF desteği için:
implementation("io.coil-kt:coil-gif:2.6.0")
}
ImageLoader'ı özelleştirmek için ImageLoaderFactory kullanılır — Application.onCreate'de oluşturulan bir singleton. Fabrikada önbellek sınırlarını, HTTP istemcisini, özel kod çözücüleri ve günlük kaydını yapılandırabilirsiniz. Varsayılan olarak Coil, hazır bir bağlantı havuzuyla OkHttp kullanır.
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()
}
}
Sıkça Sorulan Sorular
Coil, Kotlin ile coroutine'ler kullanılarak yazılmış Android için bir görsel yükleme kütüphanesidir. Ağ, kaynaklar veya dosya sisteminden bitmap görsellerinin asenkron olarak yüklenmesi, önbelleğe alınması ve görüntülenmesi için kullanılır.
Coil %100 Kotlin ile yazılmıştır ve Glide'daki geri arama mekanizması yerine coroutine'ler kullanır. Coil daha küçük APK boyutuna (~150 KB vs ~500 KB) ve AsyncImage aracılığıyla Jetpack Compose için yerel desteğe sahiptir.
build.gradle.kts dosyasına io.coil-kt:coil:2.6.0 bağımlılığını ekleyin. Jetpack Compose için ayrıca io.coil-kt:coil-compose:2.6.0 ekleyin. Kütüphane, ContentProvider aracılığıyla otomatik olarak bir ImageLoader kaydeder.
Coil, JPEG, PNG, WebP, BMP, SVG (coil-svg modülü aracılığıyla) ve GIF'i (coil-gif modülü aracılığıyla) destekler. AVIF ve HEIF biçimleri, Android 10+ cihazlarda özel bir kod çözücü aracılığıyla desteklenir.
Önbellek, ImageLoader.Builder aracılığıyla yapılandırılır: memoryCache heap yüzdesiyle, diskCache yol ve bayt cinsinden sınırla. Önbellek politikaları (ENABLED, DISABLED, READ_ONLY), CachePolicy aracılığıyla istek başına yapılandırılır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun