Android Coil 新手使用教程
从零上手 Coil,搞懂 1.x / 2.x / 3.x 的差异,选对主流版本。
最新稳定 3.5.0
主流 Coil 3.x
更新于 2026-08
01Coil 是什么
Coil 是一个 Kotlin 优先的 Android / 跨平台图片加载库,名字来自 Coroutine Image Loader。它的核心特点是:
- 协程优先:基于 Kotlin 协程,没有回调地狱,也不用桥接 RxJava / LiveData。
- 轻量:方法数约 2000,APK 增量小,远小于 Glide 等传统方案。
- Kotlin 原生体验:扩展函数、DSL 配置、内联优化,调用简洁。
- 格式齐全:JPEG、PNG、WebP、GIF、SVG、HEIF/HEIC、视频帧都能加载。
- UI 无侵入:
ImageView.load(...)与 Compose 的AsyncImage是一套统一加载逻辑。
一句话理解: 如果你的项目已经在用 Kotlin + 协程(尤其 Jetpack Compose),Coil 几乎不需要改动架构就能接入。
02版本全景对比(1.x / 2.x / 3.x)
这是选型的地基,先看清三代版本的区别。
1.x · 已停更
2.x · 稳定可用
3.x · 主流 3.5.0
| 维度 | Coil 1.x | Coil 2.x | Coil 3.x(主流) |
|---|---|---|---|
| 状态 | 已停止维护 | 稳定,仍被广泛使用 | 当前主流,持续更新 |
| 平台 | 仅 Android | 仅 Android | Kotlin Multiplatform:Android / iOS / JVM / JS / WASM |
| Maven 坐标 | io.coil-kt:coil | io.coil-kt:coil | io.coil-kt.coil3:coil |
| 包名 | coil | coil | coil3 |
| 最低 API | 16 / 17 | 21 | 23(3.5.0 起,此前为 21) |
| Compose 用法 | rememberImagePainter | AsyncImage / SubcomposeAsyncImage | 同 2.x,且支持 Compose Multiplatform |
| 网络加载 | 内置 OkHttp | 内置 OkHttp | 解耦,需引入 coil-network-okhttp 或 coil-network-ktor |
| 磁盘缓存 | 依赖 OkHttp 的 Cache | 自带 DiskCache(可中断解码) | 自带 DiskCache |
| Bitmap 池 | 有 | 已移除 | 已移除 |
| 默认 Scale | FILL | FIT | FIT |
| 版本管理 | 手动写版本号 | 手动写版本号 | 支持 BOM 统一版本 |
3.x 最大的两个变化: ① 变成真正的 Kotlin 多平台库(一套图片逻辑跑 Android + iOS + 桌面 + Web);② 把网络依赖拆出去了,想要网络加载必须显式加
coil-network-okhttp 或 coil-network-ktor,这也顺带让纯本地加载的应用可以不带任何网络库。03现在该用哪个版本
- 新项目(纯 Android 或 Compose 多平台):直接用 Coil 3.5.x。这是当前主流,特性最新、维护活跃。
- 存量 Android-only 项目:在用 Coil 2.x 完全没问题,生态成熟、资料多,可逐步迁移到 3.x。
- Coil 1.x:已过时,不推荐任何新项目使用;仅在维护极老代码时才会碰到。
选型提醒: Coil 3.x 最低 API 已提升到 23(3.5.0 起)。若你的应用还需支持 Android 5.0(API 21/22),要么留在 Coil 3.4.x 及更早,要么继续使用 Coil 2.x。
04快速开始(以 Coil 3.x 为例)
在 build.gradle.kts 中引入依赖。
方式一:逐条引入(最简单)
// build.gradle.kts (Module :app)
dependencies {
// 核心 + 网络(OkHttp 引擎)
implementation("io.coil-kt.coil3:coil:3.5.0")
implementation("io.coil-kt.coil3:coil-network-okhttp:3.5.0")
// Jetpack Compose 集成
implementation("io.coil-kt.coil3:coil-compose:3.5.0")
// 扩展格式(GIF / SVG 等,按需添加)
implementation("io.coil-kt.coil3:coil-gif:3.5.0") // Android only
implementation("io.coil-kt.coil3:coil-svg:3.5.0") // 跨平台
}
方式二:用 BOM 统一版本(多模块推荐)
多个模块都要用 Coil 时,用 BOM 锁定同一版本,避免各模块版本错配:
dependencies {
// BOM 统一管理版本,下方无需再写版本号
implementation(platform("io.coil-kt.coil3:coil-bom:3.5.0"))
implementation("io.coil-kt.coil3:coil")
implementation("io.coil-kt.coil3:coil-network-okhttp")
implementation("io.coil-kt.coil3:coil-compose")
}
新手易错: Coil 3 以后不内置网络库。只写
coil 而不加 coil-network-okhttp,加载网络图片会失败。纯加载本地资源(drawable / file / res)则可不加。05基础用法(详细):各种图片来源怎么加载
Coil 3 的 load(data) / AsyncImage(model) 能接收多种数据类型,下面按真实开发场景逐个讲。
核心认知: Coil 3 会根据
data 的类型自动选 Fetcher——网络地址走网络库,Int 当资源 ID,File/Uri 走本地/文件,Bitmap/ByteArray 直接解码。你几乎只要把「数据源」传进去,其余交给 Coil。5.1 加载网络图片(最常见:列表头像 / 商品图)
// 场景:RecyclerView 头像,要求渐显 + 失败兜底 + 圆形裁剪
import coil3.load
import coil3.transform.CircleCropTransformation
imageView.load("https://cdn.example.com/avatar/10086.png") {
crossfade(true)
placeholder(R.drawable.avatar_placeholder) // 加载中的占位
error(R.drawable.avatar_error) // 出错显示默认图
transformations(CircleCropTransformation()) // 圆形头像
size(96, 96) // 明确目标尺寸,省内存
}
性能习惯: 列表里尽量用
size() 或让 ImageView 自适应尺寸,Coil 会按显示尺寸下采样,避免把 2000px 大图原样解码进内存。5.2 加载 drawable 资源(App 内置图)
把资源 ID 直接传进去即可,Coil 会当成本地资源解码:
// 场景:引导页默认底图、空状态图、默认头像
imageView.load(R.drawable.empty_state)
imageView.load(R.drawable.default_banner)
5.3 加载 mipmap 资源(应用图标等)
重点: mipmap 和 drawable 一样,直接传资源 ID(R.mipmap.xxx) 即可,不需要拼 URI。
// 场景:关于页展示 App 图标、启动页 Logo、通知大图标预览
imageView.load(R.mipmap.ic_launcher) // 应用图标
imageView.load(R.mipmap.ic_launcher_round)
Coil 3 的坑: 3.x 不再支持
android.resource://包名/drawable/文件名 这种字符串 URI(会影响资源压缩)。必须用资源 ID(R.drawable.xxx / R.mipmap.xxx)或数字 ID 形式 android.resource://包名/12345678。老代码里写死的字符串资源 URI 要改成传 ID。5.4 加载本地文件 File(沙盒 / 缓存 / 下载目录)
// 场景:拍照保存到 filesDir、已下载的离线图、裁剪后临时文件
import java.io.File
val file = File(context.filesDir, "user_avatar.jpg")
imageView.load(file) // 直接传 File 对象
// 或传 file:// URI
imageView.load(Uri.fromFile(file))
5.5 加载相册返回的 ContentProvider Uri(系统选择器)
// 场景:调用系统相册/拍照,onActivityResult 拿到的 content:// Uri
import android.net.Uri
private val pick = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
uri ?: return@registerForActivityResult
imageView.load(uri) // 直接传 android.net.Uri
}
pick.launch("image/*")
系统相册返回的是
content:// 的 ContentProvider Uri,Coil 3 原生支持,无需你自己把流读到 File 再加载。5.6 加载 Bitmap / ByteArray(已存在于内存的数据)
// 场景:相机直接返回 Bitmap、接口下发图片二进制、加水印后的结果
imageView.load(bitmap) // 直接显示 Bitmap
imageView.load(byteArray) // 直接解码 ByteArray
5.7 Compose 中各来源的写法对照
Compose 用 AsyncImage 的 model 参数,传的值类型和上面完全对应:
| 来源 | ImageView 写法 | Compose model 写法 |
|---|---|---|
| 网络 | load(url) | model = url |
| drawable | load(R.drawable.x) | model = R.drawable.x |
| mipmap | load(R.mipmap.ic_launcher) | model = R.mipmap.ic_launcher |
| 本地文件 | load(file) | model = file |
| 相册 Uri | load(uri) | model = uri |
| Bitmap | load(bitmap) | model = bitmap |
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import androidx.compose.ui.platform.LocalContext
// Compose 中同样能配占位/变换,用 ImageRequest 包装
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(R.mipmap.ic_launcher)
.crossfade(true)
.placeholder(R.drawable.ph)
.build(),
contentDescription = null,
contentScale = ContentScale.Fit,
)
5.8 监听加载状态(骨架屏 / 错误态)
import coil3.compose.SubcomposeAsyncImage
import coil3.compose.SubcomposeAsyncImageContent
import coil3.compose.AsyncImagePainter
SubcomposeAsyncImage(
model = "https://example.com/photo.jpg",
contentDescription = null,
) {
when (painter.state) {
is AsyncImagePainter.State.Loading -> /* 显示骨架屏 */
is AsyncImagePainter.State.Error -> /* 显示错误重试按钮 */
else -> SubcomposeAsyncImageContent()
}
}
06常用配置
占位、错误、渐变、变换、缩放。
占位图 / 错误图 / 淡入
imageView.load(url) {
placeholder(R.drawable.placeholder) // 加载中
error(R.drawable.error) // 失败
fallback(R.drawable.fallback) // model 为 null 时
crossfade(300) // 300ms 渐显
}
变换:圆角 / 圆形 / 灰度
Coil 3 把变换合并进了 coil-core,直接导入即可:
import coil3.transform.CircleCropTransformation
import coil3.transform.RoundedCornersTransformation
import coil3.transform.GrayscaleTransformation
imageView.load(url) {
transformations(
CircleCropTransformation(), // 圆形头像
// RoundedCornersTransformation(16f), // 圆角 16dp
// GrayscaleTransformation(), // 灰度
)
}
缩放模式
imageView.load(url) {
scale(Scale.FILL) // 填满裁剪(默认是 FIT)
}
// Compose 中用 contentScale
AsyncImage(model = url, contentScale = ContentScale.Crop, ...)
07进阶用法
自定义 ImageLoader、缓存、网络库、动图。
1) 全局自定义 ImageLoader(Coil 3 的 SingletonImageLoader.Factory)
class MyApp : Application(), SingletonImageLoader.Factory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.diskCache {
DiskCache.Builder()
.directory(cacheDir.resolve("image_cache"))
.maxSizePercent(0.02) // 最多占用 2% 空间
.build()
}
.memoryCacheMaxSizePercent(0.25)
.crossfade(true)
.build()
}
}
2) 网络库二选一
// A. OkHttp(Android / JVM 推荐,默认成熟稳定)
implementation("io.coil-kt.coil3:coil-network-okhttp:3.5.0")
// B. Ktor(跨平台 / 多端统一网络栈时选它)
implementation("io.coil-kt.coil3:coil-network-ktor:3.5.0")
implementation("io.ktor:ktor-client-okhttp:3.x") // 再配一个 Ktor 引擎
3) 加载 GIF / SVG / 视频帧
implementation("io.coil-kt.coil3:coil-gif:3.5.0") // GIF(Android only)
implementation("io.coil-kt.coil3:coil-svg:3.5.0") // SVG(跨平台)
implementation("io.coil-kt.coil3:coil-video:3.5.0") // 视频首帧
// GIF 使用方式与普通图片一致,Coil 自动识别格式
imageView.load("https://example.com/anim.gif")
记忆要点: GIF / 视频解码器目前仍是 Android only;SVG 解码器已支持多平台。需要跨端动图时,3.x 的多平台能力主要体现在静态图与 SVG 上。
08从 Coil 2.x 迁移到 3.x 的破坏性变更
老项目升级时这几处必改:
- 坐标与包名:
io.coil-kt:coil→io.coil-kt.coil3:coil,import coil→import coil3(可与 2.x 共存,但会引入两套依赖)。 - 网络组件解耦:必须显式添加
coil-network-okhttp或coil-network-ktor,否则网络图加载失败。 - ImageLoader 初始化:
Coil.setImageLoader(...)→ 在 Application 实现SingletonImageLoader.Factory并重写newImageLoader()。 - Drawable → Image:非 Android 平台用
coil3.Image;Android 上可用Drawable.asImage()/Image.asDrawable(resources)互相转换。 - Context → PlatformContext:自定义组件里
Context改为PlatformContext(Android 上仍是 Context 的别名)。 - Parameters → Extras:旧的
ParametersAPI 被Extras取代,key 改为基于对象身份(identity equality)。 - 最低 API:3.5.0 起最低 API 23,注意兜底低版本设备。
09总结与选型建议
- 新手直接上 Coil 3.5.x:跨平台、BOM 版本管理、网络解耦,是当下最值得学的版本。
- 核心三步:① 加依赖(核心 + 网络 + 可选格式)→ ②
ImageView.load()或AsyncImage加载 → ③ 用 builder 配 placeholder / 变换 / 缩放。 - 别踩两个坑:3.x 忘了加网络库会加载不出图;最低 API 23 要留意老设备。
- 老项目:Coil 2.x 依旧稳,可渐进迁移,不必强求。
下一步: 官方文档 coil-kt.github.io/coil 有完整的 API 与样例;想做 Compose 多平台图片加载,直接参考 Coil 3 的 samples 仓库。