Android Glide 使用详解
Glide 是 Android 平台上最受欢迎的图片加载库之一,由 Bump Technologies 开发,后被 Google 推荐为官方图片加载方案。
一、什么是 Glide
Glide 是一个快速、高效、开源的 Android 图片加载库,专注于:
-
平滑滚动:自动处理图片加载与列表滚动的性能平衡
-
内存优化:智能的内存缓存和磁盘缓存策略
-
GIF 支持:原生支持加载和显示 GIF 动画
-
视频缩略图:支持从视频文件中提取缩略图
二、基本集成
1. 添加依赖
groovy
// build.gradle (Module: app)
dependencies {
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
}
2. 基础用法
kotlin
// 加载网络图片
Glide.with(context)
.load("https://example.com/image.jpg")
.into(imageView)
// 加载本地资源
Glide.with(context)
.load(R.drawable.image)
.into(imageView)
// 加载本地文件
Glide.with(context)
.load(File("/path/to/image.jpg"))
.into(imageView)
// 加载 URI
Glide.with(context)
.load(uri)
.into(imageView)
三、核心 API 详解
1. with() --- 生命周期绑定
kotlin
// 绑定 Activity 生命周期(推荐)
Glide.with(activity)
// 绑定 Fragment 生命周期
Glide.with(fragment)
// 绑定 View 生命周期
Glide.with(view)
// 绑定 Application 生命周期(全局,不推荐常规使用)
Glide.with(context.applicationContext)
关键特性:Glide 会自动根据绑定的生命周期暂停/恢复/销毁请求,避免内存泄漏。
2. load() --- 数据来源
支持多种数据类型:
-
String--- URL 或文件路径 -
Uri--- 内容提供者 URI -
File--- 本地文件 -
Integer--- 资源 ID -
Drawable--- 已有 Drawable -
Bitmap--- 已有 Bitmap -
byte[]--- 字节数组 -
URL--- Java URL 对象
3. into() --- 目标视图
kotlin
// 加载到 ImageView
.into(imageView)
// 加载到自定义 Target(获取 Bitmap)
.into(object : CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
// 处理 Bitmap
}
override fun onLoadCleared(placeholder: Drawable?) {}
})
四、常用配置选项
占位图与错误图
kotlin
Glide.with(context)
.load(url)
.placeholder(R.drawable.loading) // 加载中占位图
.error(R.drawable.error) // 加载失败图
.fallback(R.drawable.empty) // 传入 null 时显示
.into(imageView)
图片变换
kotlin
Glide.with(context)
.load(url)
.centerCrop() // 居中裁剪,填满视图
.fitCenter() // 居中适配,完整显示
.circleCrop() // 圆形裁剪
.into(imageView)
尺寸调整
kotlin
Glide.with(context)
.load(url)
.override(300, 200) // 指定加载尺寸(像素)
.into(imageView)
缓存策略
kotlin
Glide.with(context)
.load(url)
.skipMemoryCache(true) // 跳过内存缓存
.diskCacheStrategy(DiskCacheStrategy.NONE) // 跳过磁盘缓存
.into(imageView)
磁盘缓存策略:
| 策略 | 说明 |
|---|---|
ALL |
缓存原始图片和转换后的图片(默认) |
NONE |
不缓存 |
DATA |
仅缓存原始图片 |
RESOURCE |
仅缓存转换后的图片 |
AUTOMATIC |
智能选择(推荐) |
三级缓存
1. 活动缓存(Active Resources)
-
作用 :缓存当前正在被使用的图片资源(即有强引用指向它的 ImageView 还在屏幕上显示)
-
特点 :使用
HashMap管理,key 是EngineKey,value 是Resource的弱引用或引用计数 -
生命周期:当 ImageView 不再引用该资源(如页面销毁、图片切换)时,从活动缓存移出,进入内存缓存
2. 内存缓存(Memory Cache)
-
作用 :缓存最近使用过但当前未被显示的图片
-
实现 :
LruResourceCache,继承自LruCache,默认大小为设备内存的某个比例(可通过MemorySizeCalculator计算) -
淘汰策略:LRU(Least Recently Used),当内存不足时淘汰最久未使用的
-
注意:从内存缓存取出的图片需要重新进入活动缓存才能使用
3. 磁盘缓存(Disk Cache)
-
作用:持久化缓存,避免重复网络请求
-
实现 :默认使用
DiskLruCache -
两种模式:
-
AUTOMATIC:根据图片来源自动决定 -
ALL:缓存原始数据和转换后的数据 -
DATA:只缓存原始数据 -
RESOURCE:只缓存转换后的数据 -
NONE:不缓存
-
加载流程(简化版)
plain
请求图片
↓
1. 检查 Active Resources(活动缓存)→ 命中则直接返回
↓ 未命中
2. 检查 Memory Cache(内存缓存)→ 命中则移入 Active Resources 并返回
↓ 未命中
3. 检查 Disk Cache(磁盘缓存)→ 命中则解码后移入 Memory/Active 并返回
↓ 未命中
4. 从网络/本地加载 → 解码 → 写入 Disk → 写入 Memory → 移入 Active → 返回
常见误区
| 错误说法 | 正确说法 |
|---|---|
| "内存缓存 = LruCache 一层" | 内存层面其实是 两层:Active Resources + LruCache |
| "三级缓存是内存、磁盘、网络" | 网络不是缓存,是数据源。三级是 Active、Memory、Disk |
五、高级用法
1. 自定义 Transformation
kotlin
class BlurTransformation(private val radius: Int) : BitmapTransformation() {
override fun transform(
pool: BitmapPool,
toTransform: Bitmap,
outWidth: Int,
outHeight: Int
): Bitmap {
// 实现高斯模糊逻辑
return blurBitmap(toTransform, radius)
}
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update("blur_$radius".toByteArray())
}
}
// 使用
Glide.with(context)
.load(url)
.transform(BlurTransformation(25))
.into(imageView)
2. 预加载图片
kotlin
// 预加载到内存和磁盘缓存(不显示)
Glide.with(context)
.load(url)
.preload(300, 200)
// 预加载到指定尺寸
Glide.with(context)
.load(url)
.preload()
3. 下载图片(不显示)
kotlin
Glide.with(context)
.asBitmap()
.load(url)
.into(object : CustomTarget<Bitmap>(300, 200) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
// 获取到 Bitmap,自行处理
}
override fun onLoadCleared(placeholder: Drawable?) {}
})
4. 加载 GIF
kotlin
// 加载 GIF(自动播放)
Glide.with(context)
.asGif()
.load(url)
.into(imageView)
// 加载为静态 Bitmap(取第一帧)
Glide.with(context)
.asBitmap()
.load(gifUrl)
.into(imageView)
5. 设置请求优先级
kotlin
Glide.with(context)
.load(url)
.priority(Priority.HIGH) // IMMEDIATE, HIGH, NORMAL, LOW
.into(imageView)
六、Glide 模块(自定义全局配置)
创建 AppGlideModule
kotlin
@GlideModule
class MyAppGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
// 设置默认占位图
builder.setDefaultRequestOptions(
RequestOptions()
.placeholder(R.drawable.loading)
.error(R.drawable.error)
)
// 设置内存缓存大小
val memoryCacheSizeBytes = 1024 * 1024 * 20 // 20MB
builder.setMemoryCache(LruResourceCache(memoryCacheSizeBytes.toLong()))
// 设置磁盘缓存
val diskCacheSizeBytes = 1024 * 1024 * 100 // 100MB
builder.setDiskCache(InternalCacheDiskCacheFactory(context, diskCacheSizeBytes.toLong()))
// 设置日志级别
builder.setLogLevel(Log.DEBUG)
}
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
// 注册自定义组件(如自定义 ModelLoader、Encoder 等)
}
// 禁用 Manifest 解析(提升初始化速度)
override fun isManifestParsingEnabled(): Boolean = false
}
七、与 Picasso / Coil 对比
| 特性 | Glide | Picasso | Coil |
|---|---|---|---|
| 体积 | 较大(~500KB) | 中等(~100KB) | 较小(依赖 Kotlin Coroutines) |
| GIF 支持 | ✅ 原生支持 | ❌ 不支持 | ✅ 支持 |
| 视频缩略图 | ✅ 支持 | ❌ 不支持 | ✅ 支持 |
| 内存占用 | 较低(复用 Bitmap) | 较高 | 较低 |
| 图片质量 | 默认 RGB_565 | 默认 ARGB_8888 | 默认 ARGB_8888 |
| Kotlin 友好 | 一般 | 一般 | ✅ 专为 Kotlin 设计 |
| 生命周期管理 | ✅ 完善 | ✅ 完善 | ✅ 完善 |
| SVG 支持 | 需扩展 | 需扩展 | ✅ 内置支持 |
八、最佳实践
✅ 推荐做法
-
始终绑定生命周期 :使用
Glide.with(activity)而非Glide.with(context) -
指定加载尺寸 :使用
.override()避免加载过大图片 -
复用 RequestOptions:
kotlin
val options = RequestOptions() .placeholder(R.drawable.loading) .error(R.drawable.error) .centerCrop() Glide.with(context).load(url1).apply(options).into(iv1) Glide.with(context).load(url2).apply(options).into(iv2) -
列表中使用:RecyclerView 中 Glide 会自动处理复用和取消请求
❌ 避免做法
-
不要在
into()中传入新创建的 ImageView -
不要在主线程进行大量图片处理
-
不要忽略占位图设置(会导致加载闪烁)
九、常见问题
| 问题 | 解决方案 |
|---|---|
| 图片加载后变形 | 确保 ImageView 的 scaleType 与 Glide 的变换一致 |
| 图片加载模糊 | 检查是否被压缩,使用 .override(Target.SIZE_ORIGINAL) |
| 内存溢出 | 使用 .override() 限制尺寸,或降低图片质量 |
| 缓存不生效 | 确保 URL 不变,或调整 diskCacheStrategy |
| 加载 HTTPS 图片失败 | 配置 OkHttp 信任所有证书(开发环境) |