Coil — o que é, conceitos-chave e ImageLoader no Android

Autor: IT Sectr Publicado: 2026-05-05 Tempo de leitura: 9 min

Coil é uma biblioteca para carregar imagens no Android, escrita em Kotlin e construída sobre corrotinas. De acordo com a documentação oficial, a biblioteca suporta Memory Cache, Disk Cache e transformações com aceleração de hardware. Coil se destaca pelo tamanho mínimo do APK (cerca de 150 KB) e total compatibilidade com Jetpack Compose.

Principais pontos

  • Coil é uma biblioteca para carregar imagens no Android que usa Kotlin Coroutines e Kotlin Serialization.
  • ImageLoader é o componente central que gerencia requisições, cache e transformações de imagens.
  • Memory Cache armazena imagens bitmap decodificadas na RAM para acesso instantâneo.
  • Disk Cache salva arquivos comprimidos no armazenamento para trabalho offline e redução de tráfego.
  • Jetpack Compose — a biblioteca suporta AsyncImage e SubcomposeAsyncImage para UI declarativa.

O que é Coil?

Coil (Coroutine Image Loader) é uma biblioteca para carregar imagens no Android, totalmente escrita em Kotlin e que utiliza corrotinas para operações assíncronas. Ela fornece uma API unificada para carregar imagens bitmap da rede, recursos, sistema de arquivos e Content Provider, com cache automático em vários níveis.

Ao contrário do Glide e Picasso, o Coil usa Kotlin Coroutines em vez de cadeias de callbacks, tornando o código mais linear e previsível. Todas as operações de carregamento e decodificação são executadas em threads de fundo através do dispatcher Dispatchers.IO, com resultados entregues na thread principal sem alternância explícita.

O Coil suporta transformações (Round, Blur, Grayscale), animações de transição, SVG e GIF, bem como Targets personalizados para exibição não padrão. De acordo com o Google I/O 2023, o Coil é recomendado em tutoriais oficiais do Jetpack Compose junto com o Glide.

  • Tamanho do APK — cerca de 150 KB (contra 500 KB do Glide)
  • Versão mínima do Android — API 21 (Lollipop)
  • Dependência — Kotlin Coroutines (integrada)

Como funciona o Coil: ImageLoader e ImageRequest

ImageLoader é o componente principal do Coil, responsável por executar requisições de carregamento e gerenciar o cache. Cada instância contém referências ao MemoryCache, DiskCache, BitmapPool e um pool de corrotinas. Por padrão, é usado um singleton criado através de Coil.imageLoader(context).

ImageRequest

ImageRequest é um objeto que descreve uma única requisição de carregamento de imagem: fonte de dados (URL, URI, recurso Int), ImageView ou Target de destino, transformações, configurações de cache e placeholder. O ImageRequest é construído através de um builder, garantindo flexibilidade e legibilidade.

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

Após a construção, o ImageRequest é passado para o ImageLoader através de enqueue ou execute. O método enqueue inicia uma corrotina e retorna um Disposable, permitindo cancelar o carregamento ao sair da tela. O método execute é uma função suspend que retorna um Result diretamente.

Fluxo de execução da requisição

O ImageLoader verifica sequencialmente MemoryCache, DiskCache e apenas em caso de falha de ambos executa uma requisição de rede através de HttpEngine. Após o carregamento, os bytes são decodificados em um Bitmap considerando o tamanho alvo, transformações são aplicadas, o resultado é armazenado em ambos os caches e passado para o Target.

  • Memory Cache — verificado primeiro, chave é URL + parâmetros
  • Disk Cache — verificado em falha de memória, chave é MD5 da URL
  • HttpEngine — OkHttp por padrão, personalizável através de componente

Componentes principais do Coil

O Coil é construído sobre uma arquitetura de componentes com capacidade de substituir qualquer parte através de Injeção de Dependência. Todos os componentes são registrados no ImageLoaderFactory e passados ao construtor do ImageLoader através do builder.

ImageLoader

ImageLoader é o ponto de entrada para todas as operações de carregamento. Cada instância contém um pool de corrotinas, BitmapPool, MemoryCache, DiskCache e uma lista de interceptadores. Por padrão, uma instância global é criada, mas para testes unitários, instâncias separadas com caches isolados podem ser criadas.

MemoryCache

MemoryCache é um cache em memória baseado em LRU (Least Recently Used) que armazena objetos Bitmap decodificados. O tamanho máximo padrão é 25% da memória disponível do aplicativo, mas não menos que 32 MB. A chave do cache é formada por URL + tamanho + transformações, evitando a recuperação de imagens desatualizadas.

DiskCache

DiskCache é um cache baseado em arquivos para dados brutos (JPEG, PNG, WebP) e metadados decodificados. Ele está localizado no diretório de cache do aplicativo e suporta limpeza automática quando o limite é excedido. As operações de disco são realizadas através de DiskCache.Builder com configuração de diretório e tamanho máximo.

Níveis de cache no Coil

Coil implementa uma estratégia de cache em vários níveis que minimiza requisições de rede e acelera a exibição de imagens. Cada nível tem seu próprio propósito e tempo de vida dos dados.

NívelTipo de armazenamentoTempo de vidaTamanho padrão
Memory CacheBitmap na RAMAté despejo LRU25% do heap, a partir de 32 MB
Disk CacheArquivos JPEG/WebPAté exceder o limite250 MB
Http CacheRespostas OkHttpConforme cabeçalhos Cache-ControlDepende do cliente HTTP

Memory Cache fornece acesso instantâneo a Bitmaps já decodificados. Disk Cache garante que o aplicativo funcione sem rede (offline-first) após o primeiro carregamento. Http Cache no nível OkHttp lida com requisições condicionais com ETag e If-Modified-Since.

Políticas de cache são configuradas por requisição através de CachePolicy com três valores: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Por exemplo, para avatares de usuários, pode-se definir READ_ONLY para Memory Cache e ENABLED para Disk Cache.

Exemplos de uso do Coil em Kotlin

O Coil fornece vários métodos de integração dependendo da arquitetura do aplicativo. Vamos ver três cenários principais com exemplos de código funcionais.

Carregamento em ImageView através de extensão

load é uma função de extensão para ImageView, a maneira mais simples de carregar uma imagem em uma linha. A função aceita URL, URI, recurso Int ou File, juntamente com todos os parâmetros opcionais através de um configurador lambda.

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

O método load retorna um Disposable, que pode ser cancelado no onDestroy ou ao reutilizar a View. Isso evita vazamentos de memória e requisições de rede desnecessárias durante a rolagem rápida de listas.

Uso no Jetpack Compose

AsyncImage é uma função composable para carregar imagens em UI declarativa. Aceita qualquer fonte de dados e três parâmetros opcionais para estados: placeholder, error e success.

kotlin
@Composable
fun NetworkImage(url: String) {
    AsyncImage(
        model = url,
        contentDescription = "imagem de rede",
        placeholder = ColorPainter(Color.Gray),
        error = ColorPainter(Color.Red)
    )
}

SubcomposeAsyncImage é uma versão mais flexível que permite personalizar a exibição durante o carregamento através de um slot de conteúdo. Isso é útil para esqueletos (shimmer) e barras de progresso.

Target personalizado para saída não padrão

Se ImageView ou AsyncImage não forem adequados, você pode implementar um Target com um único método onSuccess que aceita um Bitmap. Isso é usado para carregar em Notification, RemoteViews ou texturas 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()
)

Comparação do Coil com outras bibliotecas

A escolha da biblioteca de carregamento de imagens depende dos requisitos do projeto. Coil compete com Glide e Picasso, cada um com seus pontos fortes. Uma comparação das principais características é apresentada na tabela.

CaracterísticaCoilGlidePicasso
IdiomaKotlin (100%)Java + KotlinJava
Tamanho do APK~150 KB~500 KB~120 KB
CorrotinasIntegradasNão (callbacks)Não (callbacks)
Jetpack ComposeSuporte nativoVia accompanistDe terceiros
GIF/WebPSim (integrado)Sim (integrado)Não
Recomendação GoogleSim (I/O 2023)SimNão

Para novos projetos em Kotlin e Jetpack Compose, o Coil se torna a escolha natural graças a zero dependências adicionais de corrotinas e tamanho mínimo. O Glide continua preferível para cenários complexos com animações e previews de vídeo. O Picasso fica atrás de ambos em funcionalidade, mas ganha em simplicidade.

Configuração do Coil em um projeto Android

A adição do Coil a um projeto Android é feita através de uma dependência Gradle. Após a adição, a biblioteca registra automaticamente um ImageLoader via ContentProvider, portanto, a inicialização manual em Application não é necessária. Se for necessária personalização, um ImageLoader personalizado é criado através do builder.

kotlin
// build.gradle.kts (app module)
dependencies {
    implementation("io.coil-kt:coil:2.6.0")
    // Para Jetpack Compose adicionalmente:
    implementation("io.coil-kt:coil-compose:2.6.0")
    // Para suporte SVG:
    implementation("io.coil-kt:coil-svg:2.6.0")
    // Para suporte GIF:
    implementation("io.coil-kt:coil-gif:2.6.0")
}

Para personalizar o ImageLoader, é usado ImageLoaderFactory — um singleton criado em Application.onCreate. Na fábrica, você pode configurar limites de cache, cliente HTTP, decodificadores personalizados e log. Por padrão, o Coil usa OkHttp com um pool de conexões pronto.

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

Perguntas frequentes

O que é Coil e para que é usado?

Coil é uma biblioteca para carregar imagens no Android, escrita em Kotlin usando corrotinas. É usada para carregamento assíncrono, cache e exibição de imagens bitmap da rede, recursos ou sistema de arquivos.

Como o Coil difere do Glide?

O Coil é escrito 100% em Kotlin e usa corrotinas em vez do mecanismo de callbacks do Glide. O Coil tem um tamanho de APK menor (~150 KB vs ~500 KB) e suporte nativo ao Jetpack Compose através do AsyncImage.

Como adicionar o Coil a um projeto Kotlin?

Adicione a dependência io.coil-kt:coil:2.6.0 ao build.gradle.kts. Para Jetpack Compose, adicione também io.coil-kt:coil-compose:2.6.0. A biblioteca registra automaticamente um ImageLoader via ContentProvider.

Quais tipos de imagem o Coil suporta?

Coil suporta JPEG, PNG, WebP, BMP, SVG (através do módulo coil-svg) e GIF (através do módulo coil-gif). Os formatos AVIF e HEIF são suportados através de um decodificador personalizado em dispositivos com Android 10+.

Como configurar o cache no Coil?

O cache é configurado através de ImageLoader.Builder: memoryCache especificando a porcentagem do heap, diskCache com caminho e limite em bytes. As políticas de cache (ENABLED, DISABLED, READ_ONLY) são configuradas por requisição através do CachePolicy.

Resumo

  • Coil é uma biblioteca de carregamento de imagens para Kotlin com suporte completo a corrotinas e Jetpack Compose.
  • ImageLoader gerencia requisições, cache e transformações, usando dois níveis de cache: Memory Cache e Disk Cache.
  • AsyncImage e SubcomposeAsyncImage fornecem integração com Compose, suportando estados de placeholder, error e success.
  • Tamanho do APK ~150 KB faz do Coil uma das bibliotecas de carregamento de imagens mais compactas do mercado.
  • Transformações (RoundedCorners, CircleCrop, Blur) estão integradas na biblioteca e funcionam com aceleração de hardware.
  • Disk Cache fornece acesso offline a imagens carregadas anteriormente com limite de armazenamento configurável.
  • Coil é recomendado pelo Google em guias oficiais do Jetpack Compose, confirmando seu status como padrão moderno.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também