Coil — är ett bibliotek för att ladda bilder på Android, skrivet i Kotlin och byggt på coroutines. Enligt officiell dokumentation stödjer biblioteket Memory Cache, Disk Cache och transformationer med hårdvaruacceleration. Coil utmärker sig med minimal APK-storlek (cirka 150 KB) och full kompatibilitet med Jetpack Compose.
Huvudpunkter
Coil (Coroutine Image Loader) — är ett bibliotek för att ladda bilder på Android, helt skrivet i Kotlin och som använder coroutines för asynkront arbete. Det erbjuder ett enhetligt API för att ladda bitmap-bilder från nätverk, resurser, filsystem och Content Provider, med automatisk cachning på flera nivåer.
Till skillnad från Glide och Picasso använder Coil Kotlin Coroutines istället för callback-kedjor, vilket gör koden mer linjär och förutsägbar. Alla laddnings- och avkodningsoperationer utförs på bakgrundstrådar via Dispatchers.IO, och resultatet levereras till huvudtråden utan explicit växling.
Coil stödjer transformationer (Round, Blur, Grayscale), övergångsanimationer, SVG och GIF, samt anpassad Target för icke-standard visning. Enligt Google I/O 2023 rekommenderas Coil i officiella Jetpack Compose-handledningar tillsammans med Glide.
ImageLoader — Coils huvudkomponent som ansvarar för att utföra laddningsförfrågningar och hantera cache. Varje instans innehåller referenser till MemoryCache, DiskCache, BitmapPool och en pool av coroutines. Som standard används en singleton skapad via Coil.imageLoader(context).
ImageRequest — ett objekt som beskriver en enskild begäran om att ladda en bild: datakälla (URL, URI, Int-resurs), mål-ImageView eller Target, transformationer, cacheinställningar och placeholder. ImageRequest byggs via en builder, vilket ger flexibilitet och läsbarhet.
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()
Efter byggnation skickas ImageRequest till ImageLoader via enqueue eller execute. Metoden enqueue startar en coroutine och returnerar Disposable, vilket gör det möjligt att avbryta laddningen när skärmen lämnas. Metoden execute är en suspend-funktion som returnerar Result direkt.
ImageLoader kontrollerar i tur och ordning MemoryCache, DiskCache och endast vid miss av båda utförs en nätverksbegäran via HttpEngine. Efter laddning avkodas byten till Bitmap med hänsyn till målstorlek, transformationer tillämpas, resultatet sparas i båda cacharna och skickas till Target.
Coil är byggt på en komponentarkitektur med möjlighet att byta ut valfri del via Dependency Injection. Alla komponenter registreras i ImageLoaderFactory och skickas till ImageLoaders konstruktor via builder.
ImageLoader — ingångspunkt för alla laddningsoperationer. Varje instans innehåller en coroutine-pool, BitmapPool, MemoryCache, DiskCache och en lista med interceptorer. Som standard skapas en global instans, men för modulär testning kan separata instanser med isolerad cache skapas.
MemoryCache — en cache i minnet baserad på LRU (Least Recently Used) som lagrar avkodade Bitmap-objekt. Standard maximal storlek är 25% av tillgängligt appminne, men inte mindre än 32 MB. Cachenyckeln bildas av URL + storlek + transformationer, vilket utesluter leverans av en inaktuell bild.
DiskCache — en filcache för rådata (JPEG, PNG, WebP) och avkodad metadata. Finns i applikationens cachekatalog och stödjer automatisk rensning vid överskridande av gränsen. Arbete med disken utförs via DiskCache.Builder med konfiguration av katalog och maximal storlek.
Coil implementerar en flernivåstrategi för cachning som minimerar nätverksförfrågningar och påskyndar bildvisning. Varje nivå har sitt eget syfte och datas livslängd.
| Nivå | Lagringstyp | Livslängd | Standardstorlek |
|---|---|---|---|
| Memory Cache | Bitmap i minnet | Tills LRU-ersättning | 25% heap, från 32 MB |
| Disk Cache | JPEG/WebP-filer | Tills gräns överskrids | 250 MB |
| Http Cache | OkHttp-svar | Enligt Cache-Control-rubriker | Beror på HTTP-klient |
Memory Cache ger omedelbar åtkomst till redan avkodade bitmappar. Disk Cache garanterar att applikationen fungerar utan nätverk (offline-first) efter första laddningen. Http Cache på OkHttp-nivå hanterar villkorliga förfrågningar ETag och If-Modified-Since.
Cachepolicyer konfigureras per begäran via CachePolicy med tre värden: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Till exempel för användaravatarer kan READ_ONLY ställas in för Memory Cache och ENABLED för Disk Cache.
Coil erbjuder flera integrationssätt beroende på applikationens arkitektur. Låt oss titta på tre viktiga scenarier med fungerande kodexempel.
load — tilläggsfunktion för ImageView, det enklaste sättet att ladda en bild på en rad. Funktionen accepterar URL, URI, Int-resurs eller File och alla valfria parametrar via en lambdakonfigurator.
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
Metoden load returnerar en Disposable som kan avbrytas i onDestroy eller vid återanvändning av View. Detta förhindrar minnesläckor och onödiga nätverksförfrågningar vid snabb scrollning av listor.
AsyncImage — composable-funktion för att ladda bilder i deklarativt UI. Accepterar valfri datakälla och tre valfria parametrar för tillstånd: placeholder, error och success.
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "nätverksbild",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage — en mer flexibel version som tillåter anpassning av visning under laddning via en innehållsslot. Detta är användbart för skelett (shimmer) och förloppsindikatorer.
Om ImageView eller AsyncImage inte är lämpliga kan Target implementeras med en enda metod onSuccess som tar emot Bitmap. Detta används för laddning i Notification, RemoteViews eller OpenGL-textur.
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()
)
Valet av bibliotek för bildladdning beror på projektets krav. Coil konkurrerar med Glide och Picasso, som var och en har sina styrkor. Jämförelse av huvudegenskaper visas i tabellen.
| Egenskap | Coil | Glide | Picasso |
|---|---|---|---|
| Språk | Kotlin (100%) | Java + Kotlin | Java |
| APK-storlek | ~150 KB | ~500 KB | ~120 KB |
| Coroutines | Inbyggt | Nej (callback) | Nej (callback) |
| Jetpack Compose | Native stöd | Via Accompaniment | Tredje part |
| GIF/WebP | Ja (inbyggt) | Ja (inbyggt) | Nej |
| Google-rekommendation | Ja (I/O 2023) | Ja | Nej |
För nya projekt i Kotlin och Jetpack Compose blir Coil ett naturligt val tack vare noll extra beroende av coroutines och minimal storlek. Glide är fortfarande att föredra för komplexa scenarier med animationer och videoförhandsvisningar. Picasso är sämre än båda funktionellt men vinner i enkelhet.
Anslutning av Coil till ett Android-projekt görs via Gradle-beroende. Efter tillägg registrerar biblioteket automatiskt ImageLoader via ContentProvider, så manuell initiering i Application krävs inte. Vid behov av anpassning skapas en egen ImageLoader via builder.
// build.gradle.kts (app-modul)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Ytterligare för Jetpack Compose:
implementation("io.coil-kt:coil-compose:2.6.0")
// För SVG-stöd:
implementation("io.coil-kt:coil-svg:2.6.0")
// För GIF-stöd:
implementation("io.coil-kt:coil-gif:2.6.0")
}
För anpassning av ImageLoader används ImageLoaderFactory — en singleton skapad i Application.onCreate. I fabriken kan cachegränser, HTTP-klient, anpassade avkodare och loggning konfigureras. Som standard använder Coil OkHttp med en färdig anslutningspool.
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()
}
}
Vanliga frågor
Coil — ett bibliotek för att ladda bilder på Android, skrivet i Kotlin med användning av coroutines. Det används för asynkron laddning, cachning och visning av bitmap-bilder från nätverk, resurser eller filsystem.
Coil är 100% skrivet i Kotlin och använder coroutines istället för callback-mekanismen i Glide. Coil har mindre APK-storlek (~150 KB mot ~500 KB) och native stöd för Jetpack Compose via AsyncImage.
Lägg till beroendet io.coil-kt:coil:2.6.0 i build.gradle.kts. För Jetpack Compose lägg även till io.coil-kt:coil-compose:2.6.0. Biblioteket registrerar automatiskt ImageLoader via ContentProvider.
Coil stödjer JPEG, PNG, WebP, BMP, SVG (via modulen coil-svg) och GIF (via modulen coil-gif). Format AVIF och HEIF stöds via en anpassad avkodare på enheter med Android 10+.
Cache konfigureras via ImageLoader.Builder: memoryCache med angivelse av procentandel av heap, diskCache med sökväg och gräns i byte. Cachepolicy (ENABLED, DISABLED, READ_ONLY) konfigureras per begäran via CachePolicy.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också