Coil — is een bibliotheek voor het laden van afbeeldingen op Android, geschreven in Kotlin en gebouwd op basis van coroutines. Volgens de officiële documentatie ondersteunt de bibliotheek Memory Cache, Disk Cache en transformaties met hardwareversnelling. Coil onderscheidt zich door een minimale APK-grootte (ongeveer 150 KB) en volledige compatibiliteit met Jetpack Compose.
Kernpunten
Coil (Coroutine Image Loader) — is een bibliotheek voor het laden van afbeeldingen op Android, volledig geschreven in Kotlin en gebruikmakend van coroutines voor asynchrone verwerking. Het biedt een uniforme API voor het laden van bitmapafbeeldingen van het netwerk, bronnen, bestandssysteem en Content Provider, met automatische caching op meerdere niveaus.
In tegenstelling tot Glide en Picasso gebruikt Coil Kotlin Coroutines in plaats van callback-ketens, waardoor de code lineairder en voorspelbaarder wordt. Alle laad- en decodeerbewerkingen worden op de achtergrond uitgevoerd via Dispatchers.IO, en het resultaat wordt afgeleverd op de hoofdthread zonder expliciete omschakeling.
Coil ondersteunt transformaties (Round, Blur, Grayscale), overgangsanimaties, SVG en GIF, evenals aangepaste Target voor niet-standaard weergave. Volgens Google I/O 2023 wordt Coil aanbevolen in officiële Jetpack Compose-tutorials samen met Glide.
ImageLoader — de belangrijkste component van Coil, verantwoordelijk voor het uitvoeren van laadverzoeken en cachebeheer. Elke instantie bevat verwijzingen naar MemoryCache, DiskCache, BitmapPool en een pool van coroutines. Standaard wordt een singleton gebruikt dat wordt aangemaakt via Coil.imageLoader(context).
ImageRequest — een object dat één laadverzoek voor een afbeelding beschrijft: gegevensbron (URL, URI, Int-bron), doel-ImageView of Target, transformaties, cache-instellingen en placeholder. ImageRequest wordt samengesteld via een builder, wat flexibiliteit en leesbaarheid biedt.
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()
Na samenstelling wordt ImageRequest doorgegeven aan ImageLoader via enqueue of execute. De methode enqueue start een coroutine en retourneert Disposable, waarmee het laden kan worden geannuleerd bij het verlaten van het scherm. De methode execute is een suspend-functie die rechtstreeks Result retourneert.
ImageLoader controleert achtereenvolgens MemoryCache, DiskCache en alleen bij een misser van beide voert het een netwerkverzoek uit via HttpEngine. Na het laden worden de bytes gedecodeerd naar Bitmap rekening houdend met de doelgrootte, worden transformaties toegepast, wordt het resultaat in beide caches opgeslagen en doorgegeven aan Target.
Coil is gebouwd op een componentenarchitectuur waarbij elk onderdeel kan worden vervangen via Dependency Injection. Alle componenten worden geregistreerd in ImageLoaderFactory en doorgegeven aan de constructor van ImageLoader via de builder.
ImageLoader — het startpunt voor alle laadoperaties. Elke instantie bevat een coroutine-pool, BitmapPool, MemoryCache, DiskCache en een lijst met interceptors. Standaard wordt één globale instantie aangemaakt, maar voor modulair testen kunnen afzonderlijke exemplaren met geïsoleerde cache worden gemaakt.
MemoryCache — een in-memory cache op basis van LRU (Least Recently Used) die gedecodeerde Bitmap-objecten opslaat. De standaard maximale grootte is 25% van het beschikbare geheugen van de applicatie, maar niet minder dan 32 MB. De cachesleutel wordt gevormd uit URL + grootte + transformaties, wat het verstrekken van een verouderde afbeelding uitsluit.
DiskCache — een bestandscache voor ruwe gegevens (JPEG, PNG, WebP) en gedecodeerde metadata. Het bevindt zich in de cache-directory van de applicatie en ondersteunt automatische opschoning bij overschrijding van de limiet. Schijfbewerkingen worden uitgevoerd via DiskCache.Builder met configuratie van de directory en maximale grootte.
Coil implementeert een gelaagde cachestrategie die netwerkverzoeken minimaliseert en het weergeven van afbeeldingen versnelt. Elk niveau heeft zijn eigen doel en levensduur van gegevens.
| Niveau | Opslagtype | Levensduur | Standaard grootte |
|---|---|---|---|
| Memory Cache | Bitmap in geheugen | Tot LRU-vervanging | 25% heap, vanaf 32 MB |
| Disk Cache | JPEG/WebP-bestanden | Tot limietoverschrijding | 250 MB |
| Http Cache | OkHttp-antwoorden | Volgens Cache-Control-headers | Afhankelijk van HTTP-client |
Memory Cache biedt onmiddellijke toegang tot reeds gedecodeerde bitmaps. Disk Cache garandeert dat de applicatie zonder netwerk werkt (offline-first) na de eerste keer laden. Http Cache op OkHttp-niveau verwerkt voorwaardelijke verzoeken ETag en If-Modified-Since.
Cachebeleid wordt per verzoek geconfigureerd via CachePolicy met drie waarden: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Bijvoorbeeld voor gebruikersavatars kan READ_ONLY worden ingesteld voor Memory Cache en ENABLED voor Disk Cache.
Coil biedt verschillende integratiemethoden, afhankelijk van de architectuur van de applicatie. Laten we drie belangrijke scenario’s bekijken met werkende codevoorbeelden.
load — extensiefunctie voor ImageView, de eenvoudigste manier om een afbeelding in één regel te laden. De functie accepteert URL, URI, Int-bron of File en alle optionele parameters via een lambda-configurator.
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
De methode load retourneert een Disposable dat kan worden geannuleerd in onDestroy of bij hergebruik van de View. Dit voorkomt geheugenlekken en onnodige netwerkverzoeken bij snel scrollen door een lijst.
AsyncImage — composable-functie voor het laden van afbeeldingen in declaratieve UI. Het accepteert elke gegevensbron en drie optionele parameters voor statussen: placeholder, error en success.
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "netwerkafbeelding",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage — een flexibelere versie die het mogelijk maakt de weergave tijdens het laden aan te passen via een content-slot. Dit is handig voor skeletons (shimmer) en voortgangsbalken.
Als ImageView of AsyncImage niet geschikt zijn, kan Target worden geïmplementeerd met een enkele methode onSuccess die Bitmap accepteert. Dit wordt gebruikt voor laden in Notification, RemoteViews of OpenGL-textuur.
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()
)
De keuze van een bibliotheek voor het laden van afbeeldingen hangt af van de projectvereisten. Coil concurreert met Glide en Picasso, die elk hun sterke punten hebben. Een vergelijking van de belangrijkste kenmerken staat in de tabel.
| Kenmerk | Coil | Glide | Picasso |
|---|---|---|---|
| Taal | Kotlin (100%) | Java + Kotlin | Java |
| APK-grootte | ~150 KB | ~500 KB | ~120 KB |
| Coroutines | Ingebouwd | Nee (callback) | Nee (callback) |
| Jetpack Compose | Native ondersteuning | Via Accompaniment | Derde partij |
| GIF/WebP | Ja (ingebouwd) | Ja (ingebouwd) | Nee |
| Aanbeveling Google | Ja (I/O 2023) | Ja | Nee |
Voor nieuwe projecten in Kotlin en Jetpack Compose wordt Coil een natuurlijke keuze dankzij nul extra afhankelijkheid van coroutines en minimale grootte. Glide blijft de voorkeur genieten voor complexe scenario’s met animaties en videovoorbeelden. Picasso doet onder voor beide qua functionaliteit, maar wint in eenvoud.
Coil verbinden met een Android-project gebeurt via een Gradle-afhankelijkheid. Na toevoeging registreert de bibliotheek automatisch ImageLoader via ContentProvider, dus handmatige initialisatie in Application is niet vereist. Indien aanpassing nodig is, wordt een eigen ImageLoader gemaakt via de builder.
// build.gradle.kts (app-module)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Extra voor Jetpack Compose:
implementation("io.coil-kt:coil-compose:2.6.0")
// Voor SVG-ondersteuning:
implementation("io.coil-kt:coil-svg:2.6.0")
// Voor GIF-ondersteuning:
implementation("io.coil-kt:coil-gif:2.6.0")
}
Voor het aanpassen van ImageLoader wordt ImageLoaderFactory gebruikt — een singleton aangemaakt in Application.onCreate. In de fabriek kunnen cachemarges, HTTP-client, aangepaste decoders en logging worden geconfigureerd. Standaard gebruikt Coil OkHttp met een kant-en-klare verbindingspool.
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()
}
}
Veelgestelde vragen
Coil — een bibliotheek voor het laden van afbeeldingen op Android, geschreven in Kotlin met behulp van coroutines. Het wordt gebruikt voor het asynchroon laden, cachen en weergeven van bitmapafbeeldingen van het netwerk, bronnen of bestandssysteem.
Coil is 100% geschreven in Kotlin en gebruikt coroutines in plaats van het callback-mechanisme in Glide. Coil heeft een kleinere APK-grootte (~150 KB versus ~500 KB) en native ondersteuning voor Jetpack Compose via AsyncImage.
Voeg de afhankelijkheid io.coil-kt:coil:2.6.0 toe in build.gradle.kts. Voor Jetpack Compose voeg ook io.coil-kt:coil-compose:2.6.0 toe. De bibliotheek registreert automatisch ImageLoader via ContentProvider.
Coil ondersteunt JPEG, PNG, WebP, BMP, SVG (via de coil-svg module) en GIF (via de coil-gif module). AVIF- en HEIF-formaten worden ondersteund via een aangepaste decoder op apparaten met Android 10+.
De cache wordt geconfigureerd via ImageLoader.Builder: memoryCache met opgave van percentage van de heap, diskCache met pad en limiet in bytes. Cachebeleid (ENABLED, DISABLED, READ_ONLY) wordt per verzoek geconfigureerd via CachePolicy.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook