Coil — шта је то, кључни појмови и ImageLoader у Android-у

Аутор: IT Sectr Објављено: 2026-05-05 Време читања: 9 мин

Coil — је библиотека за учитавање слика на Android-у, написана у Kotlin-у и изграђена на бази корутина. Према званичној документацији, библиотека подржава Memory Cache, Disk Cache и трансформације са хардверским убрзањем. Coil се истиче минималном величином APK-а (око 150 KB) и потпуном компатибилношћу са Jetpack Compose-ом.

Главне тачке

  • Coil — библиотека за учитавање слика на Android-у која користи Kotlin Coroutines и Kotlin Serialization.
  • ImageLoader — централна компонента која управља захтевима, кеширањем и трансформацијама слика.
  • Memory Cache чува декодиране битмап слике у RAM меморији за тренутни приступ.
  • Disk Cache чува компримоване датотеке на диску за рад ван мреже и смањење саобраћаја.
  • Jetpack Compose — библиотека подржава AsyncImage и SubcomposeAsyncImage за декларативни UI.

Шта је Coil?

Coil (Coroutine Image Loader) — је библиотека за учитавање слика на Android-у, у потпуности написана у Kotlin-у и која користи корутине за асинхрони рад. Пружа јединствени API за учитавање битмап слика из мреже, ресурса, фајл система и Content Provider-а, са аутоматским кеширањем на више нивоа.

За разлику од Glide-а и Picasso-а, Coil користи Kotlin Coroutines уместо callback ланаца, што чини код линеарнијим и предвидљивијим. Све операције учитавања и декодирања се извршавају у позадинским нитима преко Dispatchers.IO, а резултат се доставља у главну нит без експлицитног пребацивања.

Coil подржава трансформације (Round, Blur, Grayscale), анимације прелаза, SVG и GIF, као и прилагођени Target за нестандардни приказ. Према Google I/O 2023, Coil се препоручује у званичним туторијалима за Jetpack Compose заједно са Glide-ом.

  • Величина APK-а — око 150 KB (наспрам 500 KB код Glide-а)
  • Минимална верзија Android-а — API 21 (Lollipop)
  • Зависност — Kotlin Coroutines (уграђена)

Како ради Coil: ImageLoader и ImageRequest

ImageLoader — главна компонента Coil-а задужена за извршавање захтева за учитавање и управљање кешом. Свака инстанца садржи референце на MemoryCache, DiskCache, BitmapPool и пул корутина. Подразумевано се користи синглтон креиран кроз Coil.imageLoader(context).

ImageRequest

ImageRequest — објекат који описује један захтев за учитавање слике: извор података (URL, URI, Int ресурс), циљни ImageView или Target, трансформације, поставке кеширања и placeholder. ImageRequest се саставља кроз builder, што обезбеђује флексибилност и читљивост.

kotlin
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()

Након састављања, ImageRequest се прослеђује ImageLoader-у кроз enqueue или execute. Метод enqueue покреће корутину и враћа Disposable, омогућавајући отказивање учитавања при напуштању екрана. Метод execute је suspend-функција која директно враћа Result.

Ток извршења захтева

ImageLoader узастопно проверава MemoryCache, DiskCache и тек при промашају оба извршава мрежни захтев кроз HttpEngine. Након учитавања, бајтови се декодирају у Bitmap узимајући у обзир циљну величину, примењују се трансформације, резултат се чува у оба кеша и прослеђује Target-у.

  • Memory Cache — проверава се прво, кључ — URL + параметри
  • Disk Cache — проверава се при одсуству у меморији, кључ — MD5 URL-а
  • HttpEngine — подразумевано OkHttp, прилагодљив кроз компоненту

Главне компоненте Coil-а

Coil је изграђен на компонентној архитектури са могућношћу замене било ког дела кроз Dependency Injection. Све компоненте се региструју у ImageLoaderFactory и прослеђују у конструктор ImageLoader-а кроз builder.

ImageLoader

ImageLoader — улазна тачка за све операције учитавања. Свака инстанца садржи пул корутина, BitmapPool, MemoryCache, DiskCache и листу пресретача. Подразумевано се креира једна глобална инстанца, али за модуларно тестирање се могу креирати одвојене инстанце са изолованим кешом.

MemoryCache

MemoryCache — кеш у меморији заснован на LRU (Least Recently Used) који чува декодиране Bitmap објекте. Подразумевана максимална величина је 25% доступне меморије апликације, али не мање од 32 MB. Кључ кеша се формира од URL-а + величине + трансформација, што искључује издавање неажурне слике.

DiskCache

DiskCache — фајл кеш за сирове податке (JPEG, PNG, WebP) и декодиране метаподатке. Налази се у кеш директоријуму апликације и подржава аутоматско чишћење при прекорачењу лимита. Рад са диском се извршава кроз DiskCache.Builder са подешавањем директоријума и максималне величине.

Нивои кеширања у Coil-у

Coil имплементира вишеслојну стратегију кеширања која минимизира мрежне захтеве и убрзава приказ слика. Сваки ниво има своју сврху и време живота података.

НивоТип складиштењаВреме животаПодразумевана величина
Memory CacheBitmap у меморијиДо истискивања LRU25% heap, од 32 MB
Disk CacheJPEG/WebP датотекеДо прекорачења лимита250 MB
Http CacheOkHttp одговориПрема Cache-Control заглављимаЗависи од HTTP клијента

Memory Cache обезбеђује тренутни приступ већ декодираним битмаповима. Disk Cache гарантује рад апликације без мреже (offline-first) након првог учитавања. Http Cache на нивоу OkHttp-а обрађује условне захтеве ETag и If-Modified-Since.

Политике кеширања се подешавају по захтеву кроз CachePolicy са три вредности: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. На пример, за аватаре корисника може се поставити READ_ONLY за Memory Cache и ENABLED за Disk Cache.

Примери коришћења Coil-а у Kotlin-у

Coil нуди неколико начина интеграције у зависности од архитектуре апликације. Размотримо три кључна сценарија са радним примерима кода.

Учитавање у ImageView кроз екстензију

load — екстензија функција за ImageView, најједноставнији начин да се учита слика у једном реду. Функција прихвата URL, URI, Int ресурс или File и све опционе параметре кроз ламбда конфигуратор.

kotlin
imageView.load("https://example.com/photo.jpg") {
    crossfade(true)
    placeholder(R.drawable.placeholder)
    error(R.drawable.error)
    size(300, 300)
    transformations(CircleCropTransformation())
}

Метод load враћа Disposable који се може отказати у onDestroy или при поновној употреби View-а. Ово спречава цурење меморије и непотребне мрежне захтеве при брзом скроловању листе.

Коришћење у Jetpack Compose-у

AsyncImage — composable функција за учитавање слика у декларативном UI-ју. Прихвата било који извор података и три опциона параметра за стања: placeholder, error и success.

kotlin
@Composable
fun NetworkImage(url: String) {
    AsyncImage(
        model = url,
        contentDescription = "мрежна слика",
        placeholder = ColorPainter(Color.Gray),
        error = ColorPainter(Color.Red)
    )
}

SubcomposeAsyncImage — флексибилнија верзија која омогућава прилагођавање приказа током учитавања кроз content слот. Ово је корисно за скелетоне (shimmer) и траке напретка.

Прилагођени Target за нестандардни излаз

Ако ImageView или AsyncImage нису одговарајући, може се имплементирати Target са јединственим методом onSuccess који прима Bitmap. Ово се користи за учитавање у Notification, RemoteViews или OpenGL текстуру.

kotlin
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()
)

Поређење Coil-а са другим библиотекама

Избор библиотеке за учитавање слика зависи од захтева пројекта. Coil се такмичи са Glide-ом и Picasso-ом, од којих свака има своје предности. Поређење главних карактеристика је приказано у табели.

КарактеристикаCoilGlidePicasso
ЈезикKotlin (100%)Java + KotlinJava
Величина APK-а~150 KB~500 KB~120 KB
КорутинеУграђенеНе (callback)Не (callback)
Jetpack ComposeИзворна подршкаКроз AccompanimentТрећа страна
GIF/WebPДа (уграђено)Да (уграђено)Не
Препорука Google-аДа (I/O 2023)ДаНе

За нове пројекте у Kotlin-у и Jetpack Compose-у, Coil постаје природни избор захваљујући нултом додатном захтеву за корутине и минималној величини. Glide остаје пожељан за сложене сценарије са анимацијама и видео прегледима. Picasso је инфериоран у односу на оба по функционалности, али побеђује у једноставности.

Подешавање Coil-а у Android пројекту

Повезивање Coil-а са Android пројектом се врши кроз Gradle зависност. Након додавања, библиотека аутоматски региструје ImageLoader кроз ContentProvider, тако да ручна иницијализација у Application-у није потребна. По потреби прилагођавања, креира се сопствени ImageLoader кроз builder.

kotlin
// build.gradle.kts (модул апликације)
dependencies {
    implementation("io.coil-kt:coil:2.6.0")
    // Додатно за Jetpack Compose:
    implementation("io.coil-kt:coil-compose:2.6.0")
    // За SVG подршку:
    implementation("io.coil-kt:coil-svg:2.6.0")
    // За GIF подршку:
    implementation("io.coil-kt:coil-gif:2.6.0")
}

За прилагођавање ImageLoader-а користи се ImageLoaderFactory — синглтон креиран у Application.onCreate. У фабрици се могу подесити лимити кеша, HTTP клијент, прилагођени декодери и логирање. Подразумевано Coil користи OkHttp са готовим пулом веза.

kotlin
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()
    }
}

Често постављана питања

Шта је Coil и за шта се користи?

Coil — библиотека за учитавање слика на Android-у, написана у Kotlin-у коришћењем корутина. Користи се за асинхроно учитавање, кеширање и приказ битмап слика из мреже, ресурса или фајл система.

Чим се Coil разликује од Glide-а?

Coil је написан 100% у Kotlin-у и користи корутине уместо callback механизма у Glide-у. Coil има мању величину APK-а (~150 KB наспрам ~500 KB) и изворну подршку за Jetpack Compose кроз AsyncImage.

Како додати Coil у Kotlin пројекат?

Додајте зависност io.coil-kt:coil:2.6.0 у build.gradle.kts. За Jetpack Compose такође додајте io.coil-kt:coil-compose:2.6.0. Библиотека аутоматски региструје ImageLoader кроз ContentProvider.

Које типове слика подржава Coil?

Coil подржава JPEG, PNG, WebP, BMP, SVG (кроз модул coil-svg) и GIF (кроз модул coil-gif). AVIF и HEIF формати се подржавају кроз прилагођени декодер на уређајима са Android 10+.

Како подесити кеш у Coil-у?

Кеш се подешава кроз ImageLoader.Builder: memoryCache са навођењем процента од heap-а, diskCache са путањом и лимитом у бајтовима. Политике кеша (ENABLED, DISABLED, READ_ONLY) се подешавају по захтеву кроз CachePolicy.

Резиме

  • Coil — библиотека за учитавање слика у Kotlin-у са пуном подршком за корутине и Jetpack Compose.
  • ImageLoader управља захтевима, кеширањем и трансформацијама, користећи два нивоа кеша: Memory Cache и Disk Cache.
  • AsyncImage и SubcomposeAsyncImage пружају интеграцију са Compose-ом, подржавајући placeholder, error и success стања.
  • Величина APK-а ~150 KB чини Coil једном од најкомпактнијих библиотека за учитавање слика на тржишту.
  • Трансформације (RoundedCorners, CircleCrop, Blur) су уграђене у библиотеку и раде са хардверским убрзањем.
  • Disk Cache обезбеђује офлајн приступ претходно учитаним сликама са подесивим лимитом складиштења.
  • Coil препоручује Google у званичним водичима за Jetpack Compose, што потврђује његов статус модерног стандарда.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође