Android图片加载 #
一、图片加载概述 #
Android图片加载涉及网络请求、内存缓存、磁盘缓存、图片解码、图片变换等多个环节,使用专业的图片加载库可以大大简化开发工作。
1.1 图片加载库对比 #
| 特性 | Glide | Coil |
|---|---|---|
| 语言 | Java | Kotlin |
| 协程支持 | 需要扩展 | 原生支持 |
| 体积 | 较大 | 较小 |
| 性能 | 优秀 | 优秀 |
| API风格 | Builder | DSL |
二、Glide #
2.1 添加依赖 #
kotlin
dependencies {
implementation("com.github.bumptech.glide:glide:4.16.0")
kapt("com.github.bumptech.glide:compiler:4.16.0")
}
2.2 基本使用 #
kotlin
// 简单加载
Glide.with(context)
.load(url)
.into(imageView)
// 加载资源图片
Glide.with(context)
.load(R.drawable.image)
.into(imageView)
// 加载本地文件
Glide.with(context)
.load(File("/path/to/image.jpg"))
.into(imageView)
2.3 占位图和错误图 #
kotlin
Glide.with(context)
.load(url)
.placeholder(R.drawable.placeholder) // 加载中占位图
.error(R.drawable.error) // 加载失败图
.fallback(R.drawable.fallback) // URL为null时的图
.into(imageView)
2.4 图片变换 #
kotlin
// 圆形图片
Glide.with(context)
.load(url)
.circleCrop()
.into(imageView)
// 圆角图片
Glide.with(context)
.load(url)
.transform(CenterCrop(), RoundedCorners(16))
.into(imageView)
// 自定义变换
Glide.with(context)
.load(url)
.transform(BlurTransformation(context, 25))
.into(imageView)
2.5 缓存策略 #
kotlin
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL) // 缓存原图和变换后的图
.diskCacheStrategy(DiskCacheStrategy.NONE) // 不缓存
.diskCacheStrategy(DiskCacheStrategy.DATA) // 只缓存原图
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) // 只缓存变换后的图
.skipMemoryCache(true) // 跳过内存缓存
.into(imageView)
2.6 加载回调 #
kotlin
Glide.with(context)
.load(url)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>,
isFirstResource: Boolean
): Boolean {
Log.e("Glide", "Load failed", e)
return false
}
override fun onResourceReady(
resource: Drawable,
model: Any,
target: Target<Drawable>?,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
Log.d("Glide", "Load success")
return false
}
})
.into(imageView)
2.7 预加载 #
kotlin
// 预加载图片到缓存
Glide.with(context)
.load(url)
.preload()
// 下载图片
Glide.with(context)
.download(url)
.submit()
2.8 清除缓存 #
kotlin
// 清除内存缓存(在主线程)
Glide.get(context).clearMemory()
// 清除磁盘缓存(在子线程)
Thread {
Glide.get(context).clearDiskCache()
}.start()
三、Coil #
3.1 添加依赖 #
kotlin
dependencies {
implementation("io.coil-kt:coil:2.5.0")
}
3.2 基本使用 #
kotlin
// 简单加载
imageView.load(url)
// 带配置加载
imageView.load(url) {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
transformations(CircleCropTransformation())
}
// 加载资源图片
imageView.load(R.drawable.image)
// 加载本地文件
imageView.load(File("/path/to/image.jpg"))
3.3 图片变换 #
kotlin
// 圆形图片
imageView.load(url) {
transformations(CircleCropTransformation())
}
// 圆角图片
imageView.load(url) {
transformations(RoundedCornersTransformation(16f))
}
// 高斯模糊
imageView.load(url) {
transformations(BlurTransformation(context, 25f))
}
// 组合变换
imageView.load(url) {
transformations(
CircleCropTransformation(),
GrayscaleTransformation()
)
}
3.4 加载回调 #
kotlin
imageView.load(url) {
listener(
onStart = {
Log.d("Coil", "Load started")
},
onSuccess = { _, _ ->
Log.d("Coil", "Load success")
},
onError = { _, _ ->
Log.e("Coil", "Load error")
}
)
}
3.5 获取Bitmap #
kotlin
val imageLoader = context.imageLoader
val request = ImageRequest.Builder(context)
.data(url)
.target { drawable ->
val bitmap = (drawable as BitmapDrawable).bitmap
// 使用bitmap
}
.build()
imageLoader.enqueue(request)
// 或使用协程
val bitmap = context.imageLoader.execute(
ImageRequest.Builder(context)
.data(url)
.build()
).drawable?.toBitmap()
3.6 自定义ImageLoader #
kotlin
val imageLoader = ImageLoader.Builder(context)
.crossfade(true)
.okHttpClient {
OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.build()
}
.memoryCache {
MemoryCache.Builder(context)
.maxSizePercent(0.25)
.build()
}
.diskCache {
DiskCache.Builder()
.directory(context.cacheDir.resolve("image_cache"))
.maxSizeBytes(100 * 1024 * 1024) // 100MB
.build()
}
.build()
Coil.setImageLoader(imageLoader)
3.7 在Application中配置 #
kotlin
class MyApp : Application(), ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.crossfade(true)
.okHttpClient {
OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BASIC
})
.build()
}
.build()
}
}
四、RecyclerView图片加载 #
4.1 Glide在RecyclerView中使用 #
kotlin
class UserAdapter : RecyclerView.Adapter<UserViewHolder>() {
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
val user = users[position]
Glide.with(holder.itemView.context)
.load(user.avatar)
.placeholder(R.drawable.avatar_placeholder)
.circleCrop()
.into(holder.avatarView)
}
}
4.2 Coil在RecyclerView中使用 #
kotlin
class UserAdapter : RecyclerView.Adapter<UserViewHolder>() {
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
val user = users[position]
holder.avatarView.load(user.avatar) {
placeholder(R.drawable.avatar_placeholder)
transformations(CircleCropTransformation())
}
}
}
五、图片加载最佳实践 #
5.1 使用合适的图片尺寸 #
kotlin
// Glide指定尺寸
Glide.with(context)
.load(url)
.override(200, 200)
.into(imageView)
// Coil指定尺寸
imageView.load(url) {
size(200, 200)
}
5.2 使用缩略图 #
kotlin
// Glide缩略图
Glide.with(context)
.load(url)
.thumbnail(
Glide.with(context)
.load(thumbnailUrl)
.override(100, 100)
)
.into(imageView)
5.3 取消请求 #
kotlin
// Glide取消请求
Glide.with(context).clear(imageView)
// Coil自动取消(在View detach时)
// 或手动取消
val disposable = imageView.load(url)
disposable.dispose()
5.4 内存优化 #
kotlin
// 使用RGB_565格式减少内存
Glide.with(context)
.load(url)
.format(DecodeFormat.PREFER_RGB_565)
.into(imageView)
// Coil
imageView.load(url) {
bitmapConfig(Bitmap.Config.RGB_565)
}
六、总结 #
本章详细介绍了Android图片加载:
- 图片加载库的选择
- Glide的使用方法
- Coil的使用方法
- RecyclerView中的图片加载
- 最佳实践
选择合适的图片加载库并正确使用,可以有效提升应用的性能和用户体验。
最后更新:2026-03-26