一、Glide 是什么?Android 图片加载的 “智能管家”
Glide 是 Android 开发中最流行的图片加载库,核心功能包括:
- 高效加载:支持网络、本地图片加载,自动适配屏幕尺寸;
- 三级缓存:内存、磁盘、资源池多层缓存,避免重复解码;
- 生命周期绑定:自动跟随 Activity/Fragment 生命周期,防止内存泄漏;
- 图片转换:内置圆角、高斯模糊等特效,支持自定义转换。
二、核心架构:Glide 的 “流水线作业”
Glide 的工作流程像一条自动化生产线,分为四大模块:
1. 加载模块:图片从哪来?
- 数据源:网络(HTTP)、本地文件(SD 卡)、资源文件(res/drawable)、二进制流(byte [])。
- 核心类:
ModelLoader(负责从数据源获取图片)。 - 示例:加载网络图片时,
HttpUrlLoader会通过 OkHttp 下载图片数据。
2. 缓存模块:三级缓存策略(超市进货模型)
plaintext
内存缓存(货架) → 磁盘缓存(仓库) → 资源池(二手市场) → 网络/本地(厂家进货)
-
内存缓存(LruResourceCache) :
用 LRU(最近最少使用)算法管理,默认占应用内存的 15%-25%。- 命中时直接从内存取图,无需解码,速度最快(类似超市货架取货)。
-
磁盘缓存(DiskLruCache) :
存储解码后的图片文件,默认在AppData/cache/glide目录。- 内存未命中时,从磁盘读取并解码(类似仓库调货)。
-
资源池(ActiveResource) :
存储正在使用的图片资源,使用完后回收再利用(类似二手商品循环)。
3. 解码模块:二进制数据→Bitmap
-
按需解码:根据目标 View 尺寸解码,避免加载全尺寸图片。
- 例如:ImageView 宽高 100px,Glide 会将原图解码为 100px 尺寸。
-
格式优化:
- WebP 格式比 JPG 小 30%,Glide 自动支持;
- ARGB_8888(高质量)与 RGB_565(低质量)自动切换。
4. 生命周期模块:自动管理加载任务
-
与 Activity/Fragment 绑定:
通过SupportRequestManagerFragment监听生命周期,在onStop时暂停加载,onDestroy时取消任务(避免内存泄漏)。 -
示例:
java
// 在 Activity 中加载图片,Glide 自动管理生命周期 Glide.with(this).load(url).into(imageView);
三、关键流程:从调用 into () 到图片显示
-
构建请求:
Glide.with(context).load(url).into(imageView) -
尺寸计算:根据 ImageView 的 LayoutParams 计算目标宽高
-
缓存查找:
- 先查内存缓存,命中则直接显示;
- 未命中则查磁盘缓存,命中则解码后显示;
- 都未命中则发起网络 / 本地加载。
-
资源解码:将二进制数据转为 Bitmap,按目标尺寸缩放
-
图片显示:通过
ViewTarget绑定 ImageView,设置动画效果
四、内存优化:Glide 如何避免 OOM?
-
图片池复用(ResourcePool)
- 用过的 Bitmap 存入资源池,下次加载同尺寸图片时直接复用(类似图书馆借书还书)。
-
分层缓存策略
- 内存缓存存缩略图,磁盘缓存存原图,减少内存占用。
-
按需解码
-
只解码 View 需要的尺寸,例如:
java
// 强制解码为 200x200 像素 Glide.with(this) .load(url) .override(200, 200) .into(imageView);
-
五、实战技巧:Glide 高级功能解析
-
自定义转换:
java
// 自定义圆角转换 Glide.with(this) .load(url) .transform(new BitmapTransformation() { @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return roundCorner(toTransform, 16); // 16px 圆角 } }) .into(imageView); -
优先级控制:
java
// 列表滑动时降低图片加载优先级 Glide.with(this) .load(url) .priority(Priority.LOW) .into(imageView); -
缓存策略定制:
java
// 不缓存图片(如验证码) Glide.with(this) .load(url) .skipMemoryCache(true) // 跳过内存缓存 .diskCacheStrategy(DiskCacheStrategy.NONE) // 跳过磁盘缓存 .into(imageView);
六、Glide 与其他库对比
| 框架 | 优势 | 劣势 |
|---|---|---|
| Glide | 内存优化强、生命周期管理好 | 首次加载略慢 |
| Picasso | 简单易用 | 内存管理较弱 |
| Fresco | 大图加载(如地图) | 体积大、集成复杂 |
七、常见问题与解决方案
-
问题:列表滑动时图片闪烁
-
原因:快速滑动时旧图片未取消加载
-
方案:使用
RecyclerView的onViewRecycled方法取消加载:java
Glide.with(itemView).clear(imageView);
-
-
问题:图片模糊
-
原因:未设置
override或fitCenter缩放模式 -
方案:指定目标尺寸或缩放类型:
java
.override(500, 500) // 固定尺寸 .centerCrop() // 裁剪适配
-
-
问题:内存占用高
-
方案:启用
BitmapPool复用,或降低缓存大小:java
new GlideBuilder(context) .setMemoryCache(new LruResourceCache(10 * 1024 * 1024)) // 10MB 内存缓存 .build();
-
八、总结:Glide 的核心竞争力
Glide 通过 “三级缓存 + 按需解码 + 生命周期管理” 三大核心技术,实现了高效的图片加载体验。其设计思想可概括为:
-
空间换时间:用缓存减少重复解码
-
按需分配:只加载 View 需要的图片尺寸
-
自动管理:跟随页面生命周期释放资源
掌握这些原理,不仅能更好地使用 Glide,还能在遇到图片加载问题时快速定位优化方向(如内存泄漏、加载缓慢等)。