I’m very excited to announce the release of Coil 1.0. Coil is a Kotlin-first image loading library for Android built on top of Kotlin Coroutines. It simplifies loading images from the Internet (or any other data source) by automatically handling memory and disk caching, image downsampling, request cancellation, memory management, and more. Coil’s image pipeline is also fully extensible and supports decoding GIFs, SVGs, and video frames.
We’ve been using Coil at Instacart in both of our Android apps for over a year with great success. Over the past year we’ve refined its API, fixed plenty of bugs, improved its performance, and added support for new features including direct memory cache access, interceptors, custom transitions, and event listeners. …
Image loading libraries make it simple to fetch, decode, and display images. On Android, it’s very likely you’ll need to use one as the Android SDK mostly only exposes low-level APIs like
ImageDecoder to load images. These APIs accept an
InputStream or a
Uri however threading, memory and disk caching, request management, memory management, opening/closing any resources, and other low-level concerns are left up to the developer to handle. …
When I started working on Coil I thought domain-specific languages (DSLs) were a Kotlinesque replacement for builders. As a result, many of Coil’s public functions accept a trailing lambda for object construction:
However, over the past few months I’ve come to prefer builders over DSLs and as of Coil 0.10.0 many of the DSL functions are deprecated in favour using the builders directly:
This is a big change so I wanted to write up my reasoning about why I think you should prefer builders over DSLs.
DSLs combine the receiver’s scope with any outer scopes. As a result, the functions from any containing classes and the global scope are available inside the DSL. This makes it tougher to find specific functions when using autocomplete. Also, it can be confusing when you expect a function to exist on the receiver that doesn’t. For example,
LoadRequest.Builder has an
error function that allows you to specify a drawable to set on the
Target if the request fails. …
Jetpack Compose was announced at Google IO 2019 and is going to change how we do UI development on Android. I’ve been working a lot with the Android image APIs as I’ve been developing Coil and was curious how it treats images and how the concept of image loaders would fit in.
In the current Android UI framework
ImageView is the main way to show an image on screen. Images are represented as
Drawables, which often (though not always) wrap
Bitmaps are raw, uncompressed pixel data stored in memory.
In Jetpack Compose there is no
ImageView because there is no
View. Instead, views are replaced by
Composables which define a composable piece of UI to add to the view hierarchy. Likewise, there are no
Drawables. Instead, it’s replaced by
Image which is a minimal interface that wraps a
NativeImage. At the moment
NativeImage is defined as a
NativeImage is prefixed with a commented out
expect declaration, which is a Kotlin Multiplatform keyword 🤔. Currently there isn’t any support for animated images, though I’d expect
AnimatedImage to be added later. …
I’m excited to announce Coil — an open-source Kotlin-first image loading library for Android. Coil is fast, lightweight, modern, and treats Kotlin Coroutines, OkHttp, Okio, and AndroidX Lifecycles as first-class citizens. Coil is an acronym for Coroutine Image Loader.
With hundreds of millions of catalog listings, we load a lot of images at Instacart. On the Android team, our choice of image loading library is one of the most important parts of our app.
Here’s what Coil looks like:
While there are several image loading library options for Android developers today, we felt there was an opportunity to create a more modern, simpler product. …
It’s no secret that the Android SDK has a few rough edges.
Imagine that you’re new to Android and trying to display an image. You’ve already added the image to your
res folder and now you need to get a
Drawable. You write out
resources.getDrawable() only to find it’s deprecated and the function it’s replaced by is only available on Lollipop and above. What do you do if you need to support pre-Lollipop? If you’re like me a few years ago, you end up writing your first (of many)
if (SDK_INT >= LOLLIPOP) blocks.
EDIT: Now that Nano’s (previously RaiBlocks) transaction volume has increased, a t2.micro instance will likely drift out of sync over time. See this response.
RaiBlocks is a cryptocurrency that has exploded in popularity over the past month and a half. If you’ve invested in it and/or want to help improve the decentralization and redundancy of the network, I’d highly recommend running your own representative node.
Representative nodes are always online servers that store a copy of the transactions ledger and can serve this data to other nodes. They also improve the security of the network by voting in cases where a malicious user attempts to double spend their funds. A representative node’s voting power is based on the amount of RaiBlocks they represent (more XRB = more votes). Every RaiBlocks wallet must have a representative node and by default a wallet points to one of the official RaiBlocks nodes. …