Coil — ce este, concepte cheie și ImageLoader în Android

Autor: IT Sectr Publicat: 2026-05-05 Timp de citire: 9 min

Coil — este o bibliotecă pentru încărcarea imaginilor pe Android, scrisă în Kotlin și construită pe bază de corutine. Conform documentației oficiale, biblioteca suportă Memory Cache, Disk Cache și transformări cu accelerare hardware. Coil se evidențiază prin dimensiunea minimă a APK-ului (aproximativ 150 KB) și compatibilitatea completă cu Jetpack Compose.

Principalele puncte

  • Coil — bibliotecă pentru încărcarea imaginilor pe Android, care utilizează Kotlin Coroutines și Kotlin Serialization.
  • ImageLoader — componenta centrală care gestionează cererile, memorarea în cache și transformările imaginilor.
  • Memory Cache stochează imaginile bitmap decodate în memoria RAM pentru acces instantaneu.
  • Disk Cache salvează fișiere comprimate pe disc pentru lucru offline și reducerea traficului.
  • Jetpack Compose — biblioteca suportă AsyncImage și SubcomposeAsyncImage pentru UI declarativ.

Ce este Coil?

Coil (Coroutine Image Loader) — este o bibliotecă pentru încărcarea imaginilor pe Android, scrisă integral în Kotlin și care utilizează corutinele pentru lucru asincron. Oferă o API unificată pentru încărcarea imaginilor bitmap din rețea, resurse, sistem de fișiere și Content Provider, cu memorare automată în cache la mai multe niveluri.

Spre deosebire de Glide și Picasso, Coil folosește Kotlin Coroutines în locul lanțurilor de callback, ceea ce face codul mai liniar și mai previzibil. Toate operațiile de încărcare și decodare sunt executate pe fire de fundal prin Dispatchers.IO, iar rezultatul este livrat în firul principal fără comutare explicită.

Coil suportă transformări (Round, Blur, Grayscale), animații de tranziție, SVG și GIF, precum și Target personalizat pentru afișare non-standard. Conform Google I/O 2023, Coil este recomandat în tutorialele oficiale Jetpack Compose alături de Glide.

  • Dimensiunea APK — aproximativ 150 KB (față de 500 KB la Glide)
  • Versiunea minimă Android — API 21 (Lollipop)
  • Dependența — Kotlin Coroutines (încorporată)

Cum funcționează Coil: ImageLoader și ImageRequest

ImageLoader — componenta principală a Coil, responsabilă pentru executarea cererilor de încărcare și gestionarea cache-ului. Fiecare instanță conține referințe la MemoryCache, DiskCache, BitmapPool și un pool de corutine. În mod implicit, se folosește un singleton creat prin Coil.imageLoader(context).

ImageRequest

ImageRequest — obiect care descrie o singură cerere de încărcare a imaginii: sursa de date (URL, URI, resursă Int), ImageView sau Target de destinație, transformări, setări de cache și placeholder. ImageRequest este construit printr-un builder, ceea ce asigură flexibilitate și lizibilitate.

kotlin
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()

După construire, ImageRequest este transmis către ImageLoader prin enqueue sau execute. Metoda enqueue lansează o corutină și returnează un Disposable, permițând anularea încărcării la părăsirea ecranului. Metoda execute este o funcție suspend care returnează Result direct.

Fluxul de execuție a cererii

ImageLoader verifică succesiv MemoryCache, DiskCache și doar la lipsa ambelor execută o cerere de rețea prin HttpEngine. După încărcare, octeții sunt decodați în Bitmap ținând cont de dimensiunea țintă, se aplică transformările, rezultatul este salvat în ambele cache-uri și transmis către Target.

  • Memory Cache — verificat în primul rând, cheia — URL + parametri
  • Disk Cache — verificat la absența în memorie, cheia — MD5 al URL-ului
  • HttpEngine — în mod implicit OkHttp, personalizabil prin componentă

Componentele principale Coil

Coil este construit pe o arhitectură componentă cu posibilitatea de a înlocui orice parte prin Dependency Injection. Toate componentele sunt înregistrate în ImageLoaderFactory și transmise în constructorul ImageLoader prin builder.

ImageLoader

ImageLoader — punctul de intrare pentru toate operațiile de încărcare. Fiecare instanță conține un pool de corutine, BitmapPool, MemoryCache, DiskCache și o listă de interceptori. În mod implicit, se creează o instanță globală, dar pentru testare modulară se pot crea instanțe separate cu cache izolat.

MemoryCache

MemoryCache — cache în memorie bazat pe LRU (Least Recently Used) care stochează obiecte Bitmap decodate. Dimensiunea maximă implicită este 25% din memoria disponibilă a aplicației, dar nu mai puțin de 32 MB. Cheia cache-ului este formată din URL + dimensiune + transformări, ceea ce exclude furnizarea unei imagini neactualizate.

DiskCache

DiskCache — cache de fișiere pentru date brute (JPEG, PNG, WebP) și metadate decodate. Se află în directorul de cache al aplicației și suportă curățarea automată la depășirea limitei. Lucrul cu discul se execută prin DiskCache.Builder cu configurarea directorului și a dimensiunii maxime.

Nivelurile de cache în Coil

Coil implementează o strategie de cache pe mai multe niveluri, minimizând cererile de rețea și accelerând afișarea imaginilor. Fiecare nivel are propriul scop și durata de viață a datelor.

NivelTip de stocareDurata de viațăDimensiune implicită
Memory CacheBitmap în memoriePână la înlocuirea LRU25% heap, de la 32 MB
Disk CacheFișiere JPEG/WebPPână la depășirea limitei250 MB
Http CacheRăspunsuri OkHttpDupă antetele Cache-ControlDepinde de clientul HTTP

Memory Cache asigură acces instantaneu la bitmap-urile deja decodate. Disk Cache garantează funcționarea aplicației fără rețea (offline-first) după prima încărcare. Http Cache la nivelul OkHttp procesează cererile condiționate ETag și If-Modified-Since.

Politicile de cache se configurează per-cerere prin CachePolicy cu trei valori: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. De exemplu, pentru avatarurile utilizatorilor se poate seta READ_ONLY pentru Memory Cache și ENABLED pentru Disk Cache.

Exemple de utilizare Coil în Kotlin

Coil oferă mai multe moduri de integrare în funcție de arhitectura aplicației. Să analizăm trei scenarii cheie cu exemple de cod funcționale.

Încărcarea în ImageView prin extensie

load — funcție extensie pentru ImageView, cel mai simplu mod de a încărca o imagine într-o singură linie. Funcția acceptă URL, URI, resursă Int sau File și toți parametrii opționali printr-un configurator lambda.

kotlin
imageView.load("https://example.com/photo.jpg") {
    crossfade(true)
    placeholder(R.drawable.placeholder)
    error(R.drawable.error)
    size(300, 300)
    transformations(CircleCropTransformation())
}

Metoda load returnează un Disposable care poate fi anulat în onDestroy sau la reutilizarea View-ului. Acest lucru previne scurgerile de memorie și cererile de rețea inutile la derularea rapidă a listei.

Utilizarea în Jetpack Compose

AsyncImage — funcție composable pentru încărcarea imaginilor în UI declarativ. Acceptă orice sursă de date și trei parametri opționali pentru stări: placeholder, error și success.

kotlin
@Composable
fun NetworkImage(url: String) {
    AsyncImage(
        model = url,
        contentDescription = "imagine de rețea",
        placeholder = ColorPainter(Color.Gray),
        error = ColorPainter(Color.Red)
    )
}

SubcomposeAsyncImage — o versiune mai flexibilă care permite personalizarea afișării în timpul încărcării printr-un slot de conținut. Acest lucru este util pentru schelete (shimmer) și bare de progres.

Target personalizat pentru ieșire non-standard

Dacă ImageView sau AsyncImage nu sunt potrivite, se poate implementa Target cu o singură metodă onSuccess care primește Bitmap. Acest lucru este utilizat pentru încărcarea în Notification, RemoteViews sau texturi OpenGL.

kotlin
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()
)

Compararea Coil cu alte biblioteci

Alegerea bibliotecii pentru încărcarea imaginilor depinde de cerințele proiectului. Coil concurează cu Glide și Picasso, fiecare având puncte forte. Compararea caracteristicilor principale este prezentată în tabel.

CaracteristicăCoilGlidePicasso
LimbajKotlin (100%)Java + KotlinJava
Dimensiunea APK~150 KB~500 KB~120 KB
CorutineÎncorporateNu (callback)Nu (callback)
Jetpack ComposeSuport nativPrin AccompanimentTerță parte
GIF/WebPDa (încorporat)Da (încorporat)Nu
Recomandare GoogleDa (I/O 2023)DaNu

Pentru proiecte noi în Kotlin și Jetpack Compose, Coil devine alegerea naturală datorită dependenței zero suplimentare de corutine și dimensiunii minime. Glide rămâne preferat pentru scenarii complexe cu animații și previzualizări video. Picasso este inferior ambelor din punct de vedere funcțional, dar câștigă în simplitate.

Configurarea Coil în proiectul Android

Conectarea Coil la proiectul Android se face prin dependența Gradle. După adăugare, biblioteca înregistrează automat ImageLoader prin ContentProvider, deci inițializarea manuală în Application nu este necesară. La nevoie de personalizare, se creează propriul ImageLoader prin builder.

kotlin
// build.gradle.kts (modulul aplicației)
dependencies {
    implementation("io.coil-kt:coil:2.6.0")
    // Adițional pentru Jetpack Compose:
    implementation("io.coil-kt:coil-compose:2.6.0")
    // Pentru suport SVG:
    implementation("io.coil-kt:coil-svg:2.6.0")
    // Pentru suport GIF:
    implementation("io.coil-kt:coil-gif:2.6.0")
}

Pentru personalizarea ImageLoader se folosește ImageLoaderFactory — un singleton creat în Application.onCreate. În fabrică se pot configura limitele de cache, clientul HTTP, decodoare personalizate și logarea. În mod implicit, Coil folosește OkHttp cu un pool de conexiuni gata făcut.

kotlin
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()
    }
}

Întrebări frecvente

Ce este Coil și pentru ce se utilizează?

Coil — bibliotecă pentru încărcarea imaginilor pe Android, scrisă în Kotlin cu utilizarea corutinelor. Este folosită pentru încărcarea asincronă, memorarea în cache și afișarea imaginilor bitmap din rețea, resurse sau sistemul de fișiere.

Cu ce se deosebește Coil de Glide?

Coil este scris 100% în Kotlin și folosește corutine în locul mecanismului de callback din Glide. Coil are o dimensiune mai mică a APK-ului (~150 KB față de ~500 KB) și suport nativ pentru Jetpack Compose prin AsyncImage.

Cum se adaugă Coil la un proiect Kotlin?

Adăugați dependența io.coil-kt:coil:2.6.0 în build.gradle.kts. Pentru Jetpack Compose adăugați și io.coil-kt:coil-compose:2.6.0. Biblioteca înregistrează automat ImageLoader prin ContentProvider.

Ce tipuri de imagini suportă Coil?

Coil suportă JPEG, PNG, WebP, BMP, SVG (prin modulul coil-svg) și GIF (prin modulul coil-gif). Formatele AVIF și HEIF sunt suportate printr-un decodor personalizat pe dispozitive cu Android 10+.

Cum se configurează cache-ul în Coil?

Cache-ul se configurează prin ImageLoader.Builder: memoryCache cu specificarea procentului din heap, diskCache cu calea și limita în octeți. Politicile de cache (ENABLED, DISABLED, READ_ONLY) se configurează per-cerere prin CachePolicy.

Rezumat

  • Coil — bibliotecă de încărcare a imaginilor în Kotlin cu suport complet pentru corutine și Jetpack Compose.
  • ImageLoader gestionează cererile, memorarea în cache și transformările, utilizând două niveluri de cache: Memory Cache și Disk Cache.
  • AsyncImage și SubcomposeAsyncImage oferă integrare cu Compose, suportând stările placeholder, error și success.
  • Dimensiunea APK ~150 KB face din Coil una dintre cele mai compacte biblioteci de încărcare a imaginilor de pe piață.
  • Transformările (RoundedCorners, CircleCrop, Blur) sunt încorporate în bibliotecă și funcționează cu accelerare hardware.
  • Disk Cache asigură accesul offline la imaginile încărcate anterior cu limită de stocare configurabilă.
  • Coil este recomandat de Google în ghidurile oficiale pentru Jetpack Compose, confirmând statutul său de standard modern.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și