Glide 是 Android 开发中最强大且高效的图片加载库之一,以其内存友好性 、生命周期绑定 和多层缓存机制著称。以下从使用方法和底层原理两方面详细解析:
⭐ 一、Glide 的基本使用
1. 基础链式调用
java
Glide.with(context) // 绑定生命周期(Activity/Fragment/Application)
.load(imageUrl) // 加载源(URL/文件/资源ID/二进制流)
.placeholder(R.drawable.loading) // 占位图
.error(R.drawable.error) // 错误图
.override(300, 200) // 指定尺寸
.circleCrop() // 圆形裁剪
.diskCacheStrategy(DiskCacheStrategy.ALL) // 磁盘缓存策略
.into(imageView); // 目标 ImageView
2. 支持多种资源类型
- 网络图片 :
.load("http://example.com/image.jpg")
- 本地文件 :
.load(new File("/sdcard/image.jpg"))
- 资源ID :
.load(R.drawable.local_image)
- GIF :
.asGif().load(url)
⚙️ 二、核心功能与高级用法
1. 占位符与错误处理
placeholder()
:加载中显示的图片(主线程加载)。error()
:加载失败时显示的图片。fallback()
:当加载源为null
时的默认图(如用户头像未设置)。
2. 图片变换
- 内置变换 :
circleCrop()
(圆形)、roundedCorners(radius)
(圆角)。 - 自定义变换 :实现
BitmapTransformation
接口,例如高斯模糊等。
3. 缓存策略配置
java
.diskCacheStrategy(DiskCacheStrategy.ALL) // 缓存原始图 + 转换后的图
.skipMemoryCache(true) // 跳过内存缓存
策略 | 说明 |
---|---|
DiskCacheStrategy.ALL |
缓存原始图和转换后的图 |
DiskCacheStrategy.NONE |
禁用磁盘缓存 |
DiskCacheStrategy.DATA |
只缓存原始图(未解码) |
DiskCacheStrategy.RESOURCE |
只缓存转换后的图(解码后) |
🧠 三、缓存机制:多级高效设计
Glide 采用四级缓存(实际为三层物理缓存 + 一层逻辑缓存),优先级从高到低:
1. 活动资源(Active Resources)
- 实现 :
WeakReference<EngineResource>
弱引用集合。 - 作用:缓存当前正在使用的图片(如界面可见的 ImageView 持有的资源)。
- 特点 :无容量限制,通过引用计数(
acquired
变量)管理资源状态。当引用计数归零时,资源移入 LRU 内存缓存。
2. LRU 内存缓存(Memory Cache)
- 实现 :
LruResourceCache
(基于LinkedHashMap
,按访问顺序排序)。 - 容量:默认占应用可用内存的 1/8(可自定义)。
- 淘汰机制 :当缓存满时,移除最近最少使用的资源,移出的资源可被
BitmapPool
复用。
3. 磁盘缓存(Disk Cache)
- 实现 :
DiskLruCacheWrapper
(基于 Jake Wharton 的DiskLruCache
)。 - 文件结构 :
.0
文件:元数据(如图片宽高)。.1
文件:实际图片数据(原始图或转换后的图)。
- 策略:支持缓存原始数据(节省网络)或转换后的数据(节省 CPU)。
✅ 缓存命中流程:活动资源 → 内存缓存 → 磁盘缓存 → 网络加载。
🔄 四、生命周期管理
1. 绑定机制
- 当调用
Glide.with(Activity)
时,Glide 向该 Activity 添加一个无 UI 的 Fragment (SupportRequestManagerFragment
)。 - 此 Fragment 监听宿主生命周期事件(
onStart
/onStop
/onDestroy
):onStart
:恢复图片加载。onStop
:暂停未完成的请求。onDestroy
:清除请求并释放资源,避免内存泄漏。
2. 优势
- 自动取消请求:页面退出时终止网络请求。
- 内存优化 :在
onTrimMemory()
回调中自动清理缓存(如低内存时释放 LRU 缓存)。
⚡ 五、工作流程与线程管理
1. 核心流程:with()
→ load()
→ into()
with()
:初始化RequestManager
并绑定生命周期。load()
:创建RequestBuilder
,存储资源地址(如 URL)。into()
:- 生成缓存 Key :根据 URL、尺寸、变换参数等生成
EngineKey
。 - 查缓存:依次检查活动资源 → 内存缓存 → 磁盘缓存。
- 执行加载 :若未命中缓存,通过
EngineJob
启动DecodeJob
(解码任务):- 网络请求:默认使用
HttpURLConnection
(可替换为 OkHttp)。 - 图片解码:根据目标尺寸解码 Bitmap,避免加载全尺寸图。
- 网络请求:默认使用
- 生成缓存 Key :根据 URL、尺寸、变换参数等生成
2. 线程切换
- 主线程 → 子线程 :
EngineJob
将DecodeJob
提交到线程池(默认为 4 线程)。 - 子线程 → 主线程 :通过
Handler(Looper.getMainLooper())
将结果回调到主线程更新 UI。
🔍 六、与其他框架对比
特性 | Glide | Picasso | Fresco |
---|---|---|---|
内存占用 | RGB_565(内存减半) | ARGB_8888(全质量) | 原生内存(低版本防 OOM) |
GIF 支持 | ✅ | ❌ | ✅ |
缓存策略 | 按 ImageView 尺寸缓存 | 缓存全尺寸图 | 类似 Glide |
生命周期绑定 | ✅ | ✅ | ❌(需手动管理) |
迁移成本 | 低(直接替换 ImageView) | 低 | 高(需改用 SimpleDraweeView) |
💎 总结
- 使用场景:Glide 适用于需高效加载图片、支持 GIF、且需严格内存管理的应用(如社交/电商类 App)。
- 核心优势 :
- 四级缓存:活动资源 + LRU 内存 + 磁盘 + 网络,平衡速度与内存。
- 智能裁剪:按 ImageView 尺寸加载,避免内存浪费。
- 无缝生命周期管理:通过空白 Fragment 自动化管理请求。
- 优化建议 :
- 优先使用
RGB_565
格式减少内存占用。 - 根据场景选择磁盘缓存策略(如
DiskCacheStrategy.ALL
)。 - 自定义
OkHttp
集成以提升网络性能。
- 优先使用