Coil — egy könyvtár képek betöltésére Androidon, Kotlin nyelven írva és korutinokra építve. A hivatalos dokumentáció szerint a könyvtár támogatja a Memory Cache-t, a Disk Cache-t és a hardvergyorsításos transzformációkat. Coil kiemelkedik minimális APK méretével (kb. 150 KB) és a Jetpack Compose-zal való teljes kompatibilitásával.
Főbb pontok
Coil (Coroutine Image Loader) — egy könyvtár képek betöltésére Androidon, teljes egészében Kotlin nyelven írva, amely korutinokat használ az aszinkron működéshez. Egységes API-t biztosít bittérképes képek betöltéséhez hálózatról, erőforrásokból, fájlrendszerből és Content Provider-ből, automatikus többszintű gyorsítótárazással.
A Glide-dal és Picasso-val ellentétben a Coil Kotlin Coroutines-t használ a callback láncok helyett, ami lineárisabbá és kiszámíthatóbbá teszi a kódot. Minden betöltési és dekódolási művelet háttérszálakon történik a Dispatchers.IO-n keresztül, és az eredmény a főszálra kerül explicit átkapcsolás nélkül.
A Coil támogatja a transzformációkat (Round, Blur, Grayscale), átmeneti animációkat, SVG-t és GIF-et, valamint egyéni Target-et a nem szabványos megjelenítéshez. A Google I/O 2023 szerint a Coil ajánlott a hivatalos Jetpack Compose oktatóanyagokban a Glide mellett.
ImageLoader — a Coil fő komponense, amely a betöltési kérések végrehajtásáért és a gyorsítótár kezeléséért felelős. Minden példány hivatkozásokat tartalmaz a MemoryCache-re, DiskCache-re, BitmapPool-ra és egy korutin pool-ra. Alapértelmezés szerint a Coil.imageLoader(context) által létrehozott singleton kerül használatra.
ImageRequest — egy objektum, amely egyetlen képbetöltési kérést ír le: adatforrás (URL, URI, Int erőforrás), cél ImageView vagy Target, transzformációk, gyorsítótár beállítások és placeholder. Az ImageRequest builder-en keresztül épül fel, ami rugalmasságot és olvashatóságot biztosít.
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()
Az ImageRequest összeállítása után az enqueue vagy execute metódusokon keresztül kerül továbbításra az ImageLoader-nek. Az enqueue metódus elindít egy korutint és visszaad egy Disposable-t, lehetővé téve a betöltés megszakítását a képernyő elhagyásakor. Az execute metódus egy suspend-függvény, amely közvetlenül Result-ot ad vissza.
Az ImageLoader egymás után ellenőrzi a MemoryCache-t, a DiskCache-t, és csak mindkettő hiányában hajt végre hálózati kérést a HttpEngine-en keresztül. A betöltés után a bájtok Bitmap-pé dekódolódnak a célméret figyelembevételével, a transzformációk alkalmazásra kerülnek, az eredmény mindkét gyorsítótárba mentésre kerül és továbbításra a Target-be.
A Coil komponens alapú architektúrára épül, ahol bármely rész cserélhető a Dependency Injection segítségével. Minden komponens regisztrálásra kerül az ImageLoaderFactory-ban és továbbításra az ImageLoader konstruktorába a builder-en keresztül.
ImageLoader — a belépési pont az összes betöltési művelethez. Minden példány tartalmaz egy korutin pool-t, BitmapPool-t, MemoryCache-t, DiskCache-t és egy elfogók listáját. Alapértelmezés szerint egy globális példány jön létre, de moduláris teszteléshez külön példányok hozhatók létre elkülönített gyorsítótárral.
MemoryCache — LRU (Least Recently Used) alapú memóriabeli gyorsítótár, amely dekódolt Bitmap objektumokat tárol. Az alapértelmezett maximális méret az alkalmazás rendelkezésre álló memóriájának 25%-a, de legalább 32 MB. A gyorsítótár kulcsa URL + méret + transzformációk alapján képződik, ami kizárja az elavult kép kiadását.
DiskCache — fájl gyorsítótár nyers adatokhoz (JPEG, PNG, WebP) és dekódolt metaadatokhoz. Az alkalmazás gyorsítótár könyvtárában található és támogatja az automatikus tisztítást a határérték túllépése esetén. A lemezzel való munka a DiskCache.Builder-en keresztül történik a könyvtár és a maximális méret beállításával.
Coil többszintű gyorsítótárazási stratégiát valósít meg, amely minimalizálja a hálózati kéréseket és felgyorsítja a képek megjelenítését. Minden szintnek saját célja és adatélettartama van.
| Szint | Tárolás típusa | Élettartam | Alapértelmezett méret |
|---|---|---|---|
| Memory Cache | Bitmap memóriában | LRU kiszorításig | 25% heap, 32 MB-tól |
| Disk Cache | JPEG/WebP fájlok | Határérték túllépéséig | 250 MB |
| Http Cache | OkHttp válaszok | Cache-Control fejlécek szerint | HTTP klienstől függ |
A Memory Cache azonnali hozzáférést biztosít a már dekódolt bittérképekhez. A Disk Cache garantálja az alkalmazás hálózat nélküli működését (offline-first) az első betöltés után. Http Cache az OkHttp szintjén kezeli a feltételes kéréseket, mint az ETag és If-Modified-Since.
A gyorsítótárazási szabályzatok kérésenként konfigurálhatók a CachePolicy-n keresztül három értékkel: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Például a felhasználói avatárokhoz READ_ONLY állítható be a Memory Cache-hez és ENABLED a Disk Cache-hez.
A Coil több integrációs módot kínál az alkalmazás architektúrájától függően. Nézzünk meg három kulcsfontosságú forgatókönyvet működő kódpéldákkal.
load — kiterjesztő függvény ImageView-hoz, a legegyszerűbb mód egy kép betöltésére egy sorban. A függvény elfogad URL-t, URI-t, Int erőforrást vagy File-t és minden opcionális paramétert lambda konfigurátoron keresztül.
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
A load metódus egy Disposable-t ad vissza, amely megszakítható az onDestroy-ban vagy a View újrahasználatakor. Ez megakadályozza a memóriaszivárgást és a szükségtelen hálózati kéréseket a lista gyors görgetésekor.
AsyncImage — composable függvény képek betöltésére deklaratív UI-ban. Bármilyen adatforrást és három opcionális paramétert fogad az állapotokhoz: placeholder, error és success.
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "hálózati kép",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage — rugalmasabb verzió, amely lehetővé teszi a megjelenítés testreszabását betöltés közben egy content slot-on keresztül. Ez hasznos a vázak (shimmer) és folyamatjelző sávok esetében.
Ha az ImageView vagy AsyncImage nem megfelelő, implementálható a Target egyetlen onSuccess metódussal, amely Bitmap-ot fogad. Ez a Notification, RemoteViews vagy OpenGL textúrába történő betöltéshez használatos.
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()
)
A képbetöltő könyvtár kiválasztása a projekt követelményeitől függ. Coil versenyez a Glide-dal és Picasso-val, amelyek mindegyikének megvannak a maga erősségei. A fő jellemzők összehasonlítását a táblázat mutatja.
| Jellemző | Coil | Glide | Picasso |
|---|---|---|---|
| Nyelv | Kotlin (100%) | Java + Kotlin | Java |
| APK mérete | ~150 KB | ~500 KB | ~120 KB |
| Korutinok | Beépített | Nem (callback) | Nem (callback) |
| Jetpack Compose | Natív támogatás | Accompaniment-en keresztül | Harmadik féltől |
| GIF/WebP | Igen (beépített) | Igen (beépített) | Nem |
| Google ajánlás | Igen (I/O 2023) | Igen | Nem |
Az új Kotlin és Jetpack Compose projektekhez a Coil természetes választássá válik a korutinok nulla további függősége és a minimális méret miatt. A Glide továbbra is előnyösebb összetett forgatókönyvekhez animációkkal és videó előnézetekkel. A Picasso mindkettőnél gyengébb funkcionalitásban, de egyszerűségben nyer.
A Coil csatlakoztatása Android projekthez a Gradle függőség segítségével történik. A hozzáadás után a könyvtár automatikusan regisztrálja az ImageLoader-t a ContentProvider-en keresztül, így kézi inicializálás az Application-ben nem szükséges. Testreszabás esetén saját ImageLoader hozható létre a builder-en keresztül.
// build.gradle.kts (alkalmazás modul)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Kiegészítő Jetpack Compose-hoz:
implementation("io.coil-kt:coil-compose:2.6.0")
// SVG támogatáshoz:
implementation("io.coil-kt:coil-svg:2.6.0")
// GIF támogatáshoz:
implementation("io.coil-kt:coil-gif:2.6.0")
}
Az ImageLoader testreszabásához az ImageLoaderFactory használatos — egy singleton, amely az Application.onCreate-ban jön létre. A gyárban konfigurálhatók a gyorsítótár korlátai, a HTTP kliens, egyéni dekódolók és a naplózás. Alapértelmezés szerint a Coil az OkHttp-t használja kész kapcsolat pool-lal.
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()
}
}
Gyakran ismételt kérdések
Coil — egy könyvtár képek betöltésére Androidon, Kotlin nyelven írva korutinok használatával. Aszinkron betöltésre, gyorsítótárazásra és bittérképes képek megjelenítésére használják hálózatról, erőforrásokból vagy fájlrendszerből.
A Coil 100%-ban Kotlin nyelven íródott és korutinokat használ a Glide callback mechanizmusa helyett. A Coil kisebb APK mérettel rendelkezik (~150 KB vs ~500 KB) és natív támogatással a Jetpack Compose-hoz az AsyncImage-en keresztül.
Adja hozzá a io.coil-kt:coil:2.6.0 függőséget a build.gradle.kts fájlhoz. Jetpack Compose esetén adja hozzá a io.coil-kt:coil-compose:2.6.0 függőséget is. A könyvtár automatikusan regisztrálja az ImageLoader-t a ContentProvider-en keresztül.
Coil támogatja a JPEG, PNG, WebP, BMP, SVG (a coil-svg modulon keresztül) és GIF (a coil-gif modulon keresztül) formátumokat. Az AVIF és HEIF formátumok egyéni dekódolón keresztül támogatottak Android 10+ eszközökön.
A gyorsítótár a ImageLoader.Builder-en keresztül konfigurálható: memoryCache a heap százalékának megadásával, diskCache útvonallal és bájtban megadott korláttal. A gyorsítótár szabályzatok (ENABLED, DISABLED, READ_ONLY) a CachePolicy-en keresztül kérésenként konfigurálhatók.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is