avatarSiva Ganesh Kantamani

Summary

This context is a comprehensive guide on using Coil, a new image loader from the Instacart team, and its comparison with other libraries like Glide and Picasso.

Abstract

Coil is a new image loader from the Instacart team that uses advanced features like coroutines, OkHttp, and androidX.lifecycle. It has a smaller size compared to Glide and Fresco and offers several advanced features like image sampling, effective memory usage, and automatic canceling/pausing of requests. The guide explains how to integrate Coil into a project, its functionality, transformations, and how to cancel requests. It also compares Coil with Glide and Picasso, showcasing its ease of use and advanced features.

Opinions

  • Coil is a new and advanced image loader that is smaller in size compared to Glide and Fresco.
  • Coil uses advanced features like coroutines, OkHttp, and androidX.lifecycle.
  • Coil offers several advanced features like image sampling, effective memory usage, and automatic canceling/pausing of requests.
  • Coil is easy to use and offers a simple syntax for loading images.
  • Coil offers out-of-the-box transformations like blur, circle crop, grayscale, and rounded corners.
  • Coil effectively utilizes resources and cancels requests when the image view is detached, the context is destroyed, or another request is started with the view.
  • Coil is compared with Glide and Picasso, showcasing its ease of use and advanced features.

How to Use Coil, Kotlin First Image Loader

Better image loading on Android

Photo by Arnold Francisca on Unsplash

The Takeaway From the Article

By the end of this article, you’ll learn how to use the new image loader from the Instacart team. Along with the generic usage, you can also gain knowledge about transformations, request canceling, and image sampling features of Coil. Last but not least, there’s a migration guide from Glide and Picasso to Coil.

Introduction

Coil is the new image loader from the Instacart team, using many advanced features like coroutines, OkHttp, and androidX.lifecycles. Coil adds around 1,500 functions to your APK, which is comparable to Picasso and less then Glide and Fresco. Coil also includes several advanced features, like image sampling, effective memory usage, and automatic canceling/pausing of requests.

Coil, by default, is fully compatible with R8 optimization techniques, so there is no need for developers to add any ProGuard rules related to Coil.

Integration

Coil requires Java 8-byte code, so add the following lines in your build.gradle file to make it work.

Coil has four artifacts; each has its purpose. But mainly we use the following two :

  1. io.coil-kt: Coil: The default artifact, which has the Coil singleton. If you’re not using dependency injection or maintaining any instance of Coil across your app, then it’s better to use this artifact.
  2. io.coil-kt:coil-base: The base artifact, which does not include the Coil singleton. Prefer this artifact if you’re using dependency injection to inject Coil instance(s).

Functionality

Now that we’ve integrated the library successfully, it’s time to put Coil in action. Let’s start by loading a simple remote image. Have a look:

imageView.load("https://www.example.com/image.jpg")

As Coil is the first image loader that was developed in Kotlin, it took the leverage of using many of its advanced features, and one of them is extensions. The load is an extension function from Coil, which makes it simple to load a remote image than any other library.

With the load extension, Coil saved us the time of passing the context and creating the instance of an imageloader all the time. Have a look at the extension from Coil:

It took the leverage of taking context from imageView and creating a Coil loader. This is why native language libraries are preferable.

Placeholder and error images

Almost all libraries like Glide, Picasso, and Fresco have this feature — showing a dummy image until the original image load into the view (placeholder) and showing an error image if the request fails (error). Coil also has this feature out of the box, and the exciting part is the syntax: Implementing them is more immersed with language syntax like let and apply features in Kotlin. Have a look:

Preload images

Coil makes use of coroutines to download the images more effectively. We can download a remote image using the get suspend function. Have a look:

val image = Coil.get(imageUrl)

With the get suspend function, we can download a remote image as drawable.

Callbacks

There will be some cases where you need a callback after a remote image is downloaded. Coil covers it with the targets feature. Have a look:

There are three types of targets: Target, ViewTarget, and possibleViewTarget.

  • Target is used when the request isn’t linked to any view.
  • ViewTarget is used when the request is linked to an imageview, such as showing a placeholder until the request is completed.
  • possibleViewTarget is used if there is a need for bitmap pooling.

Transformations

Now that we’re done with different kinds of image loading techniques from Coil, it’s time to explore transformations. Transformation is a handy functionality that any image loader should contain. Out of the box, Coil comes with four transformations: blur, circle crop, grayscale, and rounded corners. The below code demonstrates the usage:

Cancel Request

Effectively utilizing the resources is the key to the performance of the app. Coil, by default, cancels the request when the imageview is detached, or the context is destroyed, or another request is started with the view. Coil covers all the cases of memory leaks by default, but there will be situations when you want to cancel the request. For that purpose, Coil returns RequestDisposable for every load request through which you can cancel the request. Have a look:

val disposable = imageView.load("https://www.example.com/image.jpg")

// Cancel the request.
disposable.dispose()

Image Sampling

Image sampling is the most advanced technique used to load the images with quality based on the size of the imageview. Suppose there is an image of size 500 x 500 on disk. Initially, Coil loads 100 x 100 and uses it as a placeholder until full quality is loaded. It works as a progressive JPEG. We can enable this while loading any imageloader request from Coil through crossfade features. Have a look:

imageView.load(imageUrl){
    crossfade(true)
}

Migration from Glide/Picasso

The Coil is an easy-to-use Kotlin native image loader. It covers all basic and advanced usages with extensions to make it simple for developers. Now, let’s compare the image loading code between Glide, Picasso, and Coil.

Basic usage:

// Glide
Glide.with(context)
    .load(url)
    .into(imageView)

// Picasso
Picasso.get()
    .load(url)
    .into(imageView)

// Coil
imageView.load(url)

Callback requests

Custom requests

Bonus

To learn more about Kotlin, read the previous parts of this Advanced Programming With Kotlin series:

To learn more about Kotlin Coroutines and other advanced features of Kotlin, read the following articles:

Thank you for reading.

Programming
Kotlin
Android
Mobile
Java
Recommended from ReadMedium