Glide源码剖析

433 阅读3分钟

几个概念

Model: 告诉glide从哪里获取图片,可以是url类型/本地文件类型/资源id类型。
Data: 输入流。
Resource: 解码后的资源,如将inputStream解码成Bitmap。
TransformedResource: 转换后的资源。
TranscodedResource: 转码后的资源。
Target: 如把Bitmap显示到目标上。

使用Glide加载图片的流程

Glide的调用

Glide.with: 参数1 -context; 参数2 -加载图片的url; 参数3 -图片显示的控件,imageView。

使用Glide加载图片时的常用参数

  • 参数context: 会影响到加载图片的生命周期。若传入的是Activity,当Activity销毁时图片加载会终止。若传入的是ApplicationContext,只有当整个应用程序被杀掉时,图片加载才会停止。
  • override: 设置图片显示到imageView的大小,压缩图片,避免图片过多地消耗内存,防止内存泄漏。
  • fitCEnter: 缩放图像使图像被完整显示到imageView,但imageView可能不会被填满。
  • centerCrop: 将图片填充imageView,但图片不一定会完整显示可能会被裁剪。
  • skipMemoryCache(true): 告知Glide不把该图片缓存到内存中,但Glide还是会利用磁盘缓存避免重复的网络请求。默认情况下,Glide会使用内存缓存,该参数为false。
  • priority(Priority.HIGH): 优先加载该图片。
  • Glide会在后台子线程做操作,再切回UI线程显示图片。

参数的底层

  • 指定context可以使Glide对不同的生命周期进行处理。

    • 指定context为Activity时,底层是利用RequestManager监控Activity的生命周期,但由于无法直接监控Activity,底层设置了一个空(无UI)的Fragment(RequestManagerFragment)来进行绑定lifecycle。
    • 指定context为ApplicationContext时,底层利用双重锁机制(单例)直接获取Application的context。
  • Glide参数的配置交由类GenericRequestBuilder

into方法

作用: 操作图片,将图片显示到ImageView上。

  • 步骤
  1. 由于是对UI操作,所以第一步是检查是否位于主线程
  2. 由于要将图片显示到ImageView上,第二步检查ImageView是否为空
  3. 对图片进行缩放,裁剪和居中
  4. 通过buildImageViewTarget封装成Target
  5. into方法返回的是Target类型,Target类继承了LifecycleListener接口,这就是为什么Glide可以绑定生命周期的原因(利用Glide.with传入的context对组件进行监听,通过组件监听灵活调用onDestroy()摧毁组件)
  6. 为避免图片错位,首先会判断当前ImageView是否复用,复用前会取消request请求。若无复用,buildRequest会创建request,setRequest将特定的ImageView和图片的request请求绑定在一起
  • setRequest实际上调用的是setTag

Glide缓存

内存缓存

正在使用的图片通过弱引用进行缓存,不再使用的图片调用LruChache进行缓存。

  1. LruCache: 通过LruCache(最近最少使用)算法,原理是将最近使用的对象的强引用存在LinkedHashMap上,并把最近最少使用的对象在缓存池达到预设值之前从内存中移除。
  2. 弱引用
  • 写入弱引用缓存
    • activeResources是一个HashMap,传入值是弱引用。
  • 从缓存中移除

加载图片的Engine.load方法

  • 内存缓存的读取步骤:
  1. loadFromCache(Lru缓存)从内存缓存中读取加载图片,如果存在就直接调用其onResourceReady(cb:callBack)
  2. 若缓存中没有该图片,继续调用loadFromActiveResources(弱引用缓存),查看正在使用的图片中是否存在,存在则调用onResourceReady
  3. 当这两种缓存都没有,EngineJob才会创建Runnable从磁盘或网络上获取图片
  • 内存缓存的写入步骤:
  1. 正在使用的图片通过弱引用进行缓存。通过Handler发送一条Message,切回主线程,写入弱引用缓存
  2. 不再使用的图片先从弱引用缓存中移除,再调用LruChache进行缓存