Coil (Coroutine Image Loader)

repository·main·Indexed 11 days ago

https://github.com/coil-kt/coil

A fast, lightweight image loading library for Android and Compose Multiplatform built with Kotlin-first principles. It leverages Coroutines, Okio, and networking libraries like OkHttp or Ktor. Features include Compose support via AsyncImage and SubcomposeAsyncImage, GIF and SVG decoding, and flexible network configuration for Coil 3.5.0.

Tokens
27.7K
Snippets
97
Records
123
Agent score
95%

What's inside Coil

  1. Overview of Coil (Coroutine Image Loader)

    main

    Coil is an image loading library for Android and Compose Multiplatform. It is designed to be fast, lightweight, and modern by leveraging Kotlin Coroutines and Okio.

    Key features include:

    • Performance: Uses memory and disk caching, image downsampling, and automatic request cancellation/pooling.
    • Lightweight: Minimal dependencies (Kotlin, Coroutines, Okio) and fully compatible with R8 code shrinking.
    • Modern Stack: Kotlin-first approach with seamless integration for Compose, Coroutines, Okio, OkHttp, and Ktor.
  2. Explore third-party libraries that work with Coil

    main

    Coil has an ecosystem of third-party libraries designed to extend its capabilities or integrate with it in specific UI frameworks. Key libraries include:

    • Telephoto: Provides building blocks for designing media experiences specifically within Compose UI.
    • Landscapist: A pluggable, highly optimized image loading library for Jetpack Compose and Kotlin Multiplatform. It can use Coil as one of its underlying engines to fetch and display network images.
    • coil-resvg: An extension that allows Coil to render SVGs using the resvg engine.
  3. What is an ImageRequest?

    main
    An ImageRequest is a value object that encapsulates all the parameters needed for an ImageLoader to perform an image load operation. This includes the source data (e.g., a URL or file), transformation parameters (like crossfade), and the destination (the target).
  4. What is an ImageLoader and how should it be used

    main

    An ImageLoader is a service object responsible for executing ImageRequests. It manages the entire image loading lifecycle, including data fetching, decoding, request management, memory management, and caching.

    Best Practice: Coil performs best when you create a single ImageLoader and share it throughout your application. This is because each ImageLoader instance maintains its own independent memory cache, disk cache, and OkHttpClient.

  5. Use ColorImage for consistent test visuals

    main
    The ColorImage class is a cross-platform testing utility that draws a colored box or fills a canvas with a specific color based on the requested width and height. It is ideal for verifying UI layouts in tests without needing real image assets.
  6. Understand the Coil 2.x Image Pipeline refactor

    main

    The image pipeline in Coil 2.x has been refactored for better flexibility. Key changes include:

    • Keyer: A new class used to compute the memory cache key for a request, replacing Fetcher.key.
    • Delegation: Mapper, Keyer, Fetcher, and Decoder can now return null to delegate the request to the next component in the pipeline.
    • Options: The Mapper.map signature now includes Options.
    • Factories: Fetcher.Factory and Decoder.Factory have been introduced. Use these to determine if a specific component is applicable; return null if it is not.
  7. Understand Java compatibility limitations in Coil

    main

    Coil is a Kotlin-first library. Because it relies on Kotlin-specific features like inlined lambdas, receiver parameters, default arguments, and extension functions, some parts of the API are not directly accessible or implementable in Java.

    Critical Limitation: suspend functions cannot be implemented in Java. If you are writing custom components for Coil, the following must be implemented in Kotlin:

    • Transformation
    • SizeResolver
    • Fetcher
    • Decoder
  8. Replace Parameters with Extras in Coil 3

    main

    The Coil 2 Parameters API has been replaced by Extras in Coil 3.

    Key differences:

    • Extras use identity equality instead of requiring a string key.
    • Extras do not support modifying the memory cache key. If you need to affect the memory cache key based on extra data, use ImageRequest.memoryCacheKeyExtra instead.
  9. Implement a custom Keyer

    main

    Keyers convert data into a portion of a cache key. This value is used as MemoryCache.Key.key when the request's output is written to the MemoryCache.

    Note: If you add a Fetcher that uses a custom data type, you must also provide a custom Keyer for that type to ensure the results are memory cacheable.

  10. How the Coil image pipeline works

    main

    Coil's image pipeline is a pluggable system that allows you to add new cache layers, data types, fetching behaviors, or image encodings. The pipeline consists of five main components executed in a specific order:

    1. Interceptors: Observe, transform, short-circuit, or retry requests.
    2. Mappers: Convert custom data types into supported types (e.g., mapping a model to a URL).
    3. Keyers: Convert data into a cache key used for the MemoryCache.
    4. Fetchers: Translate data (URL, File, etc.) into an ImageSource or Image.
    5. Decoders: Read an ImageSource and return an Image (e.g., for GIF or SVG support).

    Custom components are registered via the ComponentRegistry when building an ImageLoader.

    val imageLoader = ImageLoader.Builder(context)
        .components {
            add(CustomCacheInterceptor())
            add(ItemMapper())
            add(HttpUrlKeyer())
            add(CronetFetcher.Factory())
            add(GifDecoder.Factory())
        }
        .build()
  11. Handle ImageRequest default scale changes in Coil 2.x

    main

    In Coil 2.x, the default scale for ImageRequest has changed from Scale.FILL to Scale.FIT to align with ImageView's default ScaleType and Image's default ContentScale.

    Note: Scale is still automatically detected if you provide an ImageView as the ImageRequest.target.

  12. Handle platform-specific types in Coil 3 Multiplatform

    main

    Coil 3 is a Kotlin Multiplatform library. Because it decouples from the Android SDK, several Android-specific classes have been replaced with multiplatform alternatives:

    • Drawable $\rightarrow$ Image interface:
      • On Android: Use Drawable.asImage() and Image.asDrawable(resources) to convert.
      • On non-Android: Use Bitmap.asImage() and Image.toBitmap().
    • android.net.Uri $\rightarrow$ coil3.Uri: Custom Fetchers that previously relied on android.net.Uri must be updated to use coil3.Uri. (Note: Passing android.net.Uri as ImageRequest.data remains unaffected).
    • Context $\rightarrow$ PlatformContext:
      • On Android: PlatformContext is a type alias for Context.
      • On non-Android: Access via PlatformContext.INSTANCE.
      • In Compose Multiplatform: Use LocalPlatformContext.current.
    • Coil $\rightarrow$ SingletonImageLoader: The main class has been renamed.