1. 工作机制
-
with(),load(),into() 背后做了什么?
with() 绑定生命周期并创建RequestManager;
load() 解析资源模型;
into() 创建请求,启动缓存检查与异步加载 -
如何绑定生命周期
Glide.with(activity) 会向该Activity添加一个隐藏的Fragment。此Fragment与Activity生命周期同步,并在 onStart, onStop, onDestroy 等时机通过 RequestManager 传递信号。- 页面不可见时 (onStop) :自动暂停网络请求与动画(如GIF),节省流量与CPU。
- 页面销毁时 (onDestroy) :自动清理所有关联请求并释放资源,这是防止内存泄漏的根本。
-
缓存机制是怎么样的
四级缓存流程:活动资源(ActiveResource,弱引用)-> 内存缓存(LruResourceCache)-> 磁盘资源缓存(转换后的图)-> 磁盘数据缓存(原始数据)
2. 缓存机制
-
内存缓存具体如何工作
- 两级内存缓存
活动资源:使用 WeakReference 存储当前正在被使用的图片。这保证了多个View加载同一图片时,内存中只有一份实例且不会被回收,同时避免了LruCache中因强引用导致的“最近使用”但“正在显示”的图片被不合理挤出的问题。
LRU内存缓存:最近使用过的图片的强引用缓存,容量满时移除最久未使用的图片,从活跃资源释放的图片会移入此处。
- 两级内存缓存
-
为什么要有活动资源和内存缓存两级?
让正在使用的图片享受最快的弱引用获取,而被挤出的最近使用过的图片也能被LruCache保留一段时间,平衡性能与内存利用率 -
BitmapPool
这是一个独立的Bitmap内存复用池。当Bitmap从内存中移除时,其内存不会真正释放,而是放入池中。当需要加载新图片时,会优先从池中寻找尺寸匹配的Bitmap内存进行复用,从而极大减少JVM的GC和原生层的内存分配开销,这是防止OOM的关键。 -
磁盘缓存
通常包含 DATA (原始数据) 和 RESOURCE (转换后的图片数据) 两部分,由 DiskCacheStrategy 控制
DiskCacheStrategy:ALL(缓存所有)、RESOURCE(仅缓存处理后的图)、DATA(仅缓存原始数据)、NONE(不缓存)、AUTOMATIC(默认策略,智能选择)
3. 灵活的图片加载与解码
- ModelLoader 注册机制
这是Glide支持多数据源(URL、文件、ContentProvider等)的基石。通过注册中心,能根据模型(Model)和数据类型(Data)自动匹配对应的ModelLoader来加载原始数据(如HttpUrlLoader)。 - ResourceDecoder 解码链
数据加载后,通过解码器链(如 StreamBitmapDecoder, ByteBufferGifDecoder)将原始字节流解码为统一的 Resource 对象。这种设计使扩展新格式(如WebP、SVG)非常容易。 - Transformation 变换
图片变换(如CenterCrop,CircleCrop)作用于Bitmap,变换后的结果会缓存到磁盘的RESOURCE缓存中,避免重复变换的CPU消耗。
4. 高效的异步线程模型
Glide内部维护了多个线程池,分工明确:
- DiskCacheExecutor:用于执行磁盘缓存的读取和写入操作。
- SourceExecutor:用于执行网络请求或本地I/O等未命中缓存的数据加载。
- AnimationExecutor:专门用于解码GIF帧,保证动画流畅。
5. 如何设计一个图片加载框架
- 资源封装与解析层(统一处理网络、本地等资源)
- 缓存管理层(设计多级缓存及复用策略)
- 异步加载与线程管理层
- 图片处理层(解码、变换、缩放)
- 生命周期与视图绑定层