Glide源码分析之load方法
这里承接上篇 Glide源码分析之with方法 ,这篇将对
Glide.with(FragmentActivity).load(URL).apply(centerCropTransform()) .into(imageViewRes);
中的load
方法进行分析(PS:本人阅读的源码为 Glide 4.7 版本)
先贴出 load
方法的时序图:
接着就来依据这个时序图来阅读源码吧
Step1 load(url)
/**
* 相当于调用{@link #asDrawable() }然后调用{@link RequestBuilder #load(String)}
*
* @param string 外层传递进来的string,一般为url
* @return 依据外层传递进来的数据模式来让RequestBuilder {@link RequestBuilder} 以
* {@link Drawable}解码方法进行构建图片资源对象
*/
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
从这里我们就知道了 Glide
默认将下载的图片资源转为 Drawable
资源对象,如果对资源转换有其他指定的需求的话,我们可以在 laod
方法之前使用 asBitmap()
或者 asGif()
,做好相关的准备
Step2 asDrawable()
/**
* 通过 RequestBuilder {@link RequestBuilder} 这个构建者通过注册
* ResourceDecoder {@link ResourceDecoder} 来解析 Drawable 类型的图片资源
*
* @return 默认情况下返回 bitmapDrawable 或 GifDrawable ,也可能返回其他 Drawable 的子类
*/
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
上面提到了asBitmap()
或者 asGif()
,其实他们的内部也是一样的代码,只是传入的 Class
不一样而已:
public RequestBuilder<Bitmap> asBitmap() {
return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
}
public RequestBuilder<GifDrawable> asGif() {
return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
}
Step3 as(Drawable.class)
/**
* 通过 RequestBuilder {@link RequestBuilder} 这个构建者通过注册
* ResourceDecoder {@link ResourceDecoder} 来解析指定类型<ResourceType>的图片资源
*
* @param resourceClass 要把原始资源转换变成的图片资源类型
* @param <ResourceType> 将图片资源转换变成的类型,泛型(默认值是Drawable)
* @return 一个用于加载给定资源类的请求构建者 {@link RequestBuilder}
*/
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
这里生成了一个 RequestBuilder
对象:
/**
* 一个构建者,用于启动下载并将下载的资源转换为指定的图片资源对象,然后将图片资源对象装置在指定的控件上面
* 比方说外层传入一个Drawable类型,就把下载的原始资源转换为Drawable的图片资源对象
* 目前可以使用的原始资源转换类型有以下:
* 1.Drawable(默认类型)及其子类
* 2.Bitmap
* 3.GifDrawable
* 4.File(未知类型)
*
* @param <TransCodeType> 需要解析变成的图片资源类型,默认是Drawable类型
*
*/
public class RequestBuilder<TransCodeType> implements Cloneable,
ModelTypes<RequestBuilder<TransCodeType>> {
//暂省略...
}
Step4 RequestBuilder.load(url)
/**
* 依据外层传递进来的string来持续构建 RequestBuilder对象
* <p>
* 参数string 会作为缓存数据的缓存key值
* 如果你希望在不更改缓存key值的情况下来更换key指向的本地资源,那么需要使用 RequestOptions里面的 * signature方法{@link RequestOptions#signature(Key)}
* 专门给本地资源设置另外一个指向的key,通过key可以断开 参数string 与本地资源的指向关系
* ,从而重新从网络下载
* 不过更加方便的方法为直接使用 diskCacheStrategyOf(DiskCacheStrategy.NONE)不缓存到本地
* {@link DiskCacheStrategy#NONE}
* 和RequestOptions.skipMemoryCache(boolean)跳过内存缓存
* {@link RequestOptions#skipMemoryCache(boolean)}
* </p>
*
* @param string 外层传递进来的string,可能是一个文件路径,一个uri或网络路径,也可能是其他的
* @return RequestBuilder对象
*/
public RequestBuilder<TransCodeType> load(@Nullable String string) {
return loadGeneric(string);
}
Step5 RequestBuilder.loadGeneric(url)
/**
* 保存状态,返回RequestBuilder对象
*
* @param model 即将读取的对象,可能是一个文件路径,一个uri或网络路径,也可能是其他的
* @return RequestBuilder对象
*/
private RequestBuilder<TransCodeType> loadGeneric(Object model) {
this.model = model;
isModelSet = true;
return this;
}
这里其实就是设置了两个值,一个是我们传入的网络连接 url ,另一个是标记位,说明参数已经设置好了,可以启动下一步操作了
相比 with
方法,load
方法的流程简单不少,不过也正常,因为很多准备操作都已经弄好了,load
方法只是负责处理参数传入而已