Coil — ay isang library para sa pag-load ng mga larawan sa Android, na isinulat sa Kotlin at binuo sa batayan ng mga coroutine. Ayon sa opisyal na dokumentasyon, sinusuportahan ng library ang Memory Cache, Disk Cache at mga transformasyon na may hardware acceleration. Coil ay namumukod-tangi sa minimal na laki ng APK (mga 150 KB) at ganap na compatibility sa Jetpack Compose.
Mga pangunahing punto
Coil (Coroutine Image Loader) — ay isang library para sa pag-load ng mga larawan sa Android, na ganap na isinulat sa Kotlin at gumagamit ng mga coroutine para sa asynchronous na trabaho. Nagbibigay ito ng pinag-isang API para sa pag-load ng mga bitmap na larawan mula sa network, mga resource, file system at Content Provider, na may awtomatikong caching sa maraming antas.
Hindi tulad ng Glide at Picasso, gumagamit ang Coil ng Kotlin Coroutines sa halip na callback chain, na ginagawang mas linear at predictable ang code. Lahat ng pag-load at pag-encode ay ginagawa sa background threads sa pamamagitan ng Dispatchers.IO, at ang resulta ay inihahatid sa main thread nang walang explicit na paglipat.
Sinusuportahan ng Coil ang mga transformasyon (Round, Blur, Grayscale), transition animation, SVG at GIF, pati na rin ang custom na Target para sa hindi karaniwang pagpapakita. Ayon sa Google I/O 2023, inirerekomenda ang Coil sa mga opisyal na tutorial ng Jetpack Compose kasama ng Glide.
ImageLoader — ang pangunahing bahagi ng Coil na responsable sa pagsasagawa ng mga request sa pag-load at pamamahala ng cache. Ang bawat instance ay naglalaman ng mga reference sa MemoryCache, DiskCache, BitmapPool at pool ng mga coroutine. Bilang default, ginagamit ang singleton na nilikha sa pamamagitan ng Coil.imageLoader(context).
ImageRequest — object na naglalarawan ng isang request sa pag-load ng larawan: source ng data (URL, URI, Int resource), target na ImageView o Target, mga transformasyon, setting ng caching at placeholder. Ang ImageRequest ay binuo sa pamamagitan ng builder, na nagbibigay ng flexibility at readability.
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()
Pagkatapos mabuo, ang ImageRequest ay ipinapasa sa ImageLoader sa pamamagitan ng enqueue o execute. Ang enqueue method ay naglulunsad ng coroutine at nagbabalik ng Disposable, na nagpapahintulot sa pagkansela ng pag-load kapag umalis sa screen. Ang execute method ay isang suspend-function na direktang nagbabalik ng Result.
Sunod-sunod na sinusuri ng ImageLoader ang MemoryCache, DiskCache at kapag parehong hindi natagpuan, nagsasagawa ng network request sa pamamagitan ng HttpEngine. Pagkatapos ma-load, ang bytes ay dinedecode sa Bitmap na isinasaalang-alang ang target na laki, inaapply ang mga transformasyon, ang resulta ay nai-save sa parehong cache at ipinapasa sa Target.
Ang Coil ay binuo sa component architecture na may kakayahang palitan ang anumang bahagi sa pamamagitan ng Dependency Injection. Lahat ng component ay nirerehistro sa ImageLoaderFactory at ipinapasa sa constructor ng ImageLoader sa pamamagitan ng builder.
ImageLoader — entry point para sa lahat ng operasyon ng pag-load. Ang bawat instance ay naglalaman ng coroutine pool, BitmapPool, MemoryCache, DiskCache at listahan ng mga interceptor. Bilang default, isang global instance ang nilikha, ngunit para sa modular testing, maaaring gumawa ng magkakahiwalay na instance na may isolated na cache.
MemoryCache — in-memory cache na batay sa LRU (Least Recently Used) na nag-iimbak ng mga na-decode na Bitmap object. Ang default na maximum size ay 25% ng available memory ng application, ngunit hindi bababa sa 32 MB. Ang cache key ay nabuo mula sa URL + size + transformations, na nagbubukod ng pagbibigay ng hindi napapanahong larawan.
DiskCache — file cache para sa raw data (JPEG, PNG, WebP) at na-decode na metadata. Matatagpuan sa cache directory ng application at sumusuporta sa automatic na paglilinis kapag lumampas sa limit. Ang trabaho sa disk ay ginagawa sa pamamagitan ng DiskCache.Builder na may setting ng directory at maximum size.
Coil ay nag-iimplementa ng multi-level na caching strategy na nagmi-minimize ng network requests at nagpapabilis ng pagpapakita ng mga larawan. Bawat antas ay may sariling layunin at lifespan ng data.
| Antas | Uri ng imbakan | Lifespan | Default na laki |
|---|---|---|---|
| Memory Cache | Bitmap sa memorya | Hanggang LRU replacement | 25% heap, mula 32 MB |
| Disk Cache | JPEG/WebP file | Hanggang lumampas sa limit | 250 MB |
| Http Cache | OkHttp responses | Ayon sa Cache-Control headers | Depende sa HTTP client |
Ang Memory Cache ay nagbibigay ng agarang access sa mga na-decode na bitmap. Ang Disk Cache ay ginagarantiyahan ang paggana ng application nang walang network (offline-first) pagkatapos ng unang pag-load. Http Cache sa antas ng OkHttp ay nagpro-process ng conditional requests na ETag at If-Modified-Since.
Ang mga patakaran sa caching ay naka-configure per-request sa pamamagitan ng CachePolicy na may tatlong value: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Halimbawa, para sa mga avatar ng user, maaaring itakda ang READ_ONLY para sa Memory Cache at ENABLED para sa Disk Cache.
Nag-aalok ang Coil ng ilang paraan ng integrasyon depende sa arkitektura ng application. Tingnan natin ang tatlong pangunahing senaryo na may mga gumaganang halimbawa ng code.
load — extension function para sa ImageView, ang pinakasimpleng paraan upang mag-load ng larawan sa isang linya. Ang function ay tumatanggap ng URL, URI, Int resource o File at lahat ng opsyonal na parameter sa pamamagitan ng lambda configurator.
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
Ang load method ay nagbabalik ng Disposable na maaaring kanselahin sa onDestroy o sa muling paggamit ng View. Pinipigilan nito ang memory leaks at hindi kinakailangang network requests sa mabilis na pag-scroll ng listahan.
AsyncImage — composable function para sa pag-load ng mga larawan sa declarative UI. Tumatanggap ng anumang source ng data at tatlong opsyonal na parameter para sa mga estado: placeholder, error at success.
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "larawan sa network",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage — mas flexible na bersyon na nagpapahintulot sa pag-customize ng display habang naglo-load sa pamamagitan ng content slot. Ito ay kapaki-pakinabang para sa mga skeleton (shimmer) at progress bar.
Kung hindi angkop ang ImageView o AsyncImage, maaaring i-implement ang Target na may iisang method na onSuccess na tumatanggap ng Bitmap. Ito ay ginagamit para sa pag-load sa Notification, RemoteViews o OpenGL texture.
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()
)
Ang pagpili ng library para sa pag-load ng mga larawan ay depende sa mga kinakailangan ng proyekto. Coil ay nakikipagkumpitensya sa Glide at Picasso, na bawat isa ay may kanya-kanyang kalakasan. Ang paghahambing ng mga pangunahing katangian ay ipinapakita sa talahanayan.
| Katangian | Coil | Glide | Picasso |
|---|---|---|---|
| Wika | Kotlin (100%) | Java + Kotlin | Java |
| Laki ng APK | ~150 KB | ~500 KB | ~120 KB |
| Coroutine | Built-in | Wala (callback) | Wala (callback) |
| Jetpack Compose | Native support | Sa pamamagitan ng Accompaniment | Third party |
| GIF/WebP | Oo (built-in) | Oo (built-in) | Hindi |
| Rekomendasyon ng Google | Oo (I/O 2023) | Oo | Hindi |
Para sa mga bagong proyekto sa Kotlin at Jetpack Compose, ang Coil ay nagiging natural na pagpipilian dahil sa zero additional dependency sa coroutine at minimal na laki. Ang Glide ay nananatiling mas gusto para sa mga kumplikadong senaryo na may mga animation at video preview. Ang Picasso ay mas mababa sa pareho sa functionality, ngunit nananalo sa pagiging simple.
Ang pagkonekta ng Coil sa Android project ay ginagawa sa pamamagitan ng Gradle dependency. Pagkatapos maidagdag, awtomatikong nirerehistro ng library ang ImageLoader sa pamamagitan ng ContentProvider, kaya hindi kinakailangan ang manual initialization sa Application. Kung kailangan ng customization, ang sariling ImageLoader ay nilikha sa pamamagitan ng builder.
// build.gradle.kts (app module)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Karagdagang para sa Jetpack Compose:
implementation("io.coil-kt:coil-compose:2.6.0")
// Para sa SVG support:
implementation("io.coil-kt:coil-svg:2.6.0")
// Para sa GIF support:
implementation("io.coil-kt:coil-gif:2.6.0")
}
Para i-customize ang ImageLoader, ginagamit ang ImageLoaderFactory — singleton na nilikha sa Application.onCreate. Sa factory, maaaring i-configure ang cache limits, HTTP client, custom decoders at logging. Bilang default, gumagamit ang Coil ng OkHttp na may ready connection pool.
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()
}
}
Mga madalas itanong
Coil — library para sa pag-load ng mga larawan sa Android, na isinulat sa Kotlin gamit ang coroutine. Ito ay ginagamit para sa asynchronous na pag-load, pag-cache at pagpapakita ng mga bitmap na larawan mula sa network, resources o file system.
Ang Coil ay 100% na isinulat sa Kotlin at gumagamit ng coroutine sa halip na callback mechanism sa Glide. Ang Coil ay may mas maliit na laki ng APK (~150 KB vs ~500 KB) at native support para sa Jetpack Compose sa pamamagitan ng AsyncImage.
Idagdag ang dependency na io.coil-kt:coil:2.6.0 sa build.gradle.kts. Para sa Jetpack Compose, idagdag din ang io.coil-kt:coil-compose:2.6.0. Awtomatikong nirerehistro ng library ang ImageLoader sa pamamagitan ng ContentProvider.
Coil ay sumusuporta sa JPEG, PNG, WebP, BMP, SVG (sa pamamagitan ng coil-svg module) at GIF (sa pamamagitan ng coil-gif module). Ang mga format na AVIF at HEIF ay sinusuportahan sa pamamagitan ng custom decoder sa mga device na may Android 10+.
Ang cache ay naka-configure sa pamamagitan ng ImageLoader.Builder: memoryCache na may porsyento ng heap, diskCache na may path at limit sa bytes. Ang mga patakaran ng cache (ENABLED, DISABLED, READ_ONLY) ay naka-configure per-request sa pamamagitan ng CachePolicy.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din