Coil — je knihovna pro načítání obrázků na Androidu, napsaná v Kotlinu a postavená na korutinách. Podle oficiální dokumentace knihovna podporuje Memory Cache, Disk Cache a transformace s hardwarovou akcelerací. Coil se vyznačuje minimální velikostí APK (kolem 150 KB) a plnou kompatibilitou s Jetpack Compose.
Hlavní body
Coil (Coroutine Image Loader) — je knihovna pro načítání obrázků na Androidu, napsaná výhradně v Kotlinu a využívající korutiny pro asynchronní práci. Poskytuje jednotné API pro načítání bitmapových obrázků ze sítě, zdrojů, souborového systému a Content Provideru s automatickým ukládáním do mezipaměti na více úrovních.
Na rozdíl od Glide a Picasso používá Coil Kotlin Coroutines místo řetězců callbacků, což činí kód lineárnějším a předvídatelnějším. Všechny operace načítání a dekódování jsou prováděny na pozadí přes Dispatchers.IO a výsledek je doručen do hlavního vlákna bez explicitního přepínání.
Coil podporuje transformace (Round, Blur, Grayscale), přechodové animace, SVG a GIF, stejně jako vlastní Target pro nestandardní zobrazení. Podle Google I/O 2023 je Coil doporučován v oficiálních tutoriálech pro Jetpack Compose společně s Glide.
ImageLoader — hlavní komponenta Coilu odpovědná za provádění požadavků na načtení a správu mezipaměti. Každá instance obsahuje reference na MemoryCache, DiskCache, BitmapPool a fond korutin. Ve výchozím nastavení se používá singleton vytvořený přes Coil.imageLoader(context).
ImageRequest — objekt popisující jeden požadavek na načtení obrázku: zdroj dat (URL, URI, Int zdroj), cílový ImageView nebo Target, transformace, nastavení mezipaměti a placeholder. ImageRequest se sestavuje pomocí builderu, což zajišťuje flexibilitu a čitelnost.
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()
Po sestavení je ImageRequest předán ImageLoaderu přes enqueue nebo execute. Metoda enqueue spouští korutinu a vrací Disposable umožňující zrušení načítání při opuštění obrazovky. Metoda execute je funkce suspend vracející přímo Result.
ImageLoader postupně kontroluje MemoryCache, DiskCache a pouze při neúspěchu obou provádí síťový požadavek přes HttpEngine. Po načtení jsou bajty dekódovány do Bitmap s ohledem na cílovou velikost, aplikují se transformace, výsledek je uložen do obou mezipamětí a předán Targetu.
Coil je postaven na komponentové architektuře s možností výměny libovolné části pomocí Dependency Injection. Všechny komponenty jsou registrovány v ImageLoaderFactory a předávány do konstruktoru ImageLoaderu přes builder.
ImageLoader — vstupní bod pro všechny operace načítání. Každá instance obsahuje fond korutin, BitmapPool, MemoryCache, DiskCache a seznam zachycovačů. Ve výchozím nastavení se vytváří jedna globální instance, ale pro modulární testování lze vytvářet samostatné instance s izolovanou mezipamětí.
MemoryCache — mezipaměť v paměti založená na LRU (Least Recently Used) ukládající dekódované objekty Bitmap. Výchozí maximální velikost je 25 % dostupné paměti aplikace, ale ne méně než 32 MB. Klíč mezipaměti je tvořen z URL + velikosti + transformací, což vylučuje poskytnutí neaktuálního obrázku.
DiskCache — souborová mezipaměť pro surová data (JPEG, PNG, WebP) a dekódovaná metadata. Nachází se v adresáři mezipaměti aplikace a podporuje automatické čištění při překročení limitu. Práce s diskem se provádí přes DiskCache.Builder s nastavením adresáře a maximální velikosti.
Coil implementuje víceúrovňovou strategii ukládání do mezipaměti, která minimalizuje síťové požadavky a zrychluje zobrazování obrázků. Každá úroveň má svůj účel a životnost dat.
| Úroveň | Typ úložiště | Životnost | Výchozí velikost |
|---|---|---|---|
| Memory Cache | Bitmap v paměti | Do nahrazení LRU | 25 % heap, od 32 MB |
| Disk Cache | Soubory JPEG/WebP | Do překročení limitu | 250 MB |
| Http Cache | Odpovědi OkHttp | Podle hlaviček Cache-Control | Závisí na HTTP klientovi |
Memory Cache poskytuje okamžitý přístup k již dekódovaným bitmapám. Disk Cache zaručuje fungování aplikace bez sítě (offline-first) po prvním načtení. Http Cache na úrovni OkHttp zpracovává podmíněné požadavky ETag a If-Modified-Since.
Zásady ukládání do mezipaměti se nastavují pro každý požadavek přes CachePolicy se třemi hodnotami: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Například pro uživatelské avatary lze nastavit READ_ONLY pro Memory Cache a ENABLED pro Disk Cache.
Coil nabízí několik způsobů integrace v závislosti na architektuře aplikace. Podívejme se na tři klíčové scénáře s funkčními příklady kódu.
load — rozšiřující funkce pro ImageView, nejjednodušší způsob načtení obrázku jedním řádkem. Funkce přijímá URL, URI, Int zdroj nebo File a všechny volitelné parametry přes lambda konfigurátor.
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
Metoda load vrací Disposable, který lze zrušit v onDestroy nebo při opětovném použití View. To zabraňuje únikům paměti a zbytečným síťovým požadavkům při rychlém rolování seznamu.
AsyncImage — funkce composable pro načítání obrázků v deklarativním UI. Přijímá libovolný zdroj dat a tři volitelné parametry pro stavy: placeholder, error a success.
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "obrázek ze sítě",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage — flexibilnější verze umožňující přizpůsobení zobrazení během načítání pomocí content slotu. To je užitečné pro kostry (shimmer) a ukazatele průběhu.
Pokud ImageView nebo AsyncImage nevyhovují, lze implementovat Target s jedinou metodou onSuccess přijímající Bitmap. To se používá pro načítání do Notification, RemoteViews nebo OpenGL textury.
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()
)
Výběr knihovny pro načítání obrázků závisí na požadavcích projektu. Coil konkuruje Glide a Picasso, z nichž každá má své silné stránky. Srovnání hlavních charakteristik je uvedeno v tabulce.
| Charakteristika | Coil | Glide | Picasso |
|---|---|---|---|
| Jazyk | Kotlin (100 %) | Java + Kotlin | Java |
| Velikost APK | ~150 KB | ~500 KB | ~120 KB |
| Korutiny | Vestavěné | Ne (callback) | Ne (callback) |
| Jetpack Compose | Nativní podpora | Přes Accompaniment | Třetí strana |
| GIF/WebP | Ano (vestavěno) | Ano (vestavěno) | Ne |
| Doporučení Google | Ano (I/O 2023) | Ano | Ne |
Pro nové projekty v Kotlinu a Jetpack Compose se Coil stává přirozenou volbou díky nulové dodatečné závislosti na korutinách a minimální velikosti. Glide zůstává preferovaný pro složité scénáře s animacemi a náhledy videa. Picasso je oběma funkčně podřadné, ale vítězí jednoduchostí.
Připojení Coilu k Android projektu se provádí přes závislost Gradle. Po přidání knihovna automaticky registruje ImageLoader přes ContentProvider, takže ruční inicializace v Application není nutná. Při potřebě přizpůsobení se vytvoří vlastní ImageLoader přes builder.
// build.gradle.kts (modul aplikace)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Dodatečně pro Jetpack Compose:
implementation("io.coil-kt:coil-compose:2.6.0")
// Pro podporu SVG:
implementation("io.coil-kt:coil-svg:2.6.0")
// Pro podporu GIF:
implementation("io.coil-kt:coil-gif:2.6.0")
}
Pro přizpůsobení ImageLoaderu se používá ImageLoaderFactory — singleton vytvořený v Application.onCreate. V továrně lze nastavit limity mezipaměti, HTTP klienta, vlastní dekodéry a logování. Ve výchozím nastavení Coil používá OkHttp s připraveným fondem spojení.
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()
}
}
Často kladené dotazy
Coil — knihovna pro načítání obrázků na Androidu napsaná v Kotlinu s využitím korutin. Používá se pro asynchronní načítání, ukládání do mezipaměti a zobrazování bitmapových obrázků ze sítě, zdrojů nebo souborového systému.
Coil je napsán 100% v Kotlinu a používá korutiny místo mechanismu callbacků v Glide. Coil má menší velikost APK (~150 KB oproti ~500 KB) a nativní podporu Jetpack Compose přes AsyncImage.
Přidejte závislost io.coil-kt:coil:2.6.0 do build.gradle.kts. Pro Jetpack Compose přidejte také io.coil-kt:coil-compose:2.6.0. Knihovna automaticky zaregistruje ImageLoader přes ContentProvider.
Coil podporuje JPEG, PNG, WebP, BMP, SVG (přes modul coil-svg) a GIF (přes modul coil-gif). Formáty AVIF a HEIF jsou podporovány přes vlastní dekodér na zařízeních s Androidem 10+.
Mezipaměť se konfiguruje přes ImageLoader.Builder: memoryCache s uvedením procenta z heapu, diskCache s cestou a limitem v bajtech. Zásady mezipaměti (ENABLED, DISABLED, READ_ONLY) se nastavují pro každý požadavek přes CachePolicy.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také