Glide 源码分析之二 load
前言
在上篇中分析完了 with() 方法,Glide 分析之一 with.
本篇中,我们将通过 with() 方法返回的 RequestManager,来分析 load(resourceId) 的执行过程。
load
load() 方法在 RequestManager 中有8种重载,结合本篇的问题,这里只分析 load(resourceId) 方法。
public DrawableTypeRequest<Integer> load(Integer resourceId) {
return (DrawableTypeRequest<Integer>) fromResource().load(resourceId);(锚点1)
}
load(Integer resourceId) 方法内先调用了 fromResource() 方法:
```java`
public DrawableTypeRequest<Integer> fromResource() {
return (DrawableTypeRequest<Integer>) loadGeneric(Integer.class)(锚点2)
.signature(ApplicationVersionSignature.obtain(context));
}
看 loadGeneric(Integer.class) 方法:
```java
private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader = Glide.buildFileDescriptorModelLoader(modelClass, context);
if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
throw new IllegalArgumentException("省略");
}
return optionsApplier.apply(new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
glide, requestTracker, lifecycle, optionsApplier));
}
方法内部通过 Glide.buildStreamModelLoader() 和 Glide.buildFileDescriptorModelLoader() 方法创建两个 ModelLoader 对象用于图片加载。
这两个方法会根据传入参数,返回相应的 ModelLoader 实现类。本例中,buildStreamModelLoader() 返回 StreamResourceLoader,buildFileDescriptorModelLoader() 返回 FileDescriptorResourceLoader,这两个方法在最后有详细分析。
loadGeneric() 方法最后创建了 DrawableTypeRequest 对象,并返回。
锚点2处执行完之后继续调用 signature() 方法,标记了一个 Key,然后把 DrawableTypeRequest<Integer> 对象返回出去。
上一层拿到 DrawableTypeRequest<Integer> 对象后调用了它的 load(resourceId) 方法(见:锚点1):
public DrawableRequestBuilder<ModelType> load(ModelType model) {
super.load(model);
return this;
}
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
this.model = model;
isModelSet = true;
return this;
}
这里保存了 ModelType,在本例中就是 Integer.class.
最终 Glide.load() 方法返回 DrawableTypeRequest<Integer> 对象。
至此,load() 方法主线流程就分析完毕了,接下来会继续分析 Glide.buildStreamModelLoader() 方法是如何返回 ModelLoader 的。
Glide.buildStreamModelLoader()
public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
return buildModelLoader(modelClass, InputStream.class, context);(锚点3)
}
public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass, Context context) {
if (modelClass == null) {
···
return null;
}
return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);(锚点4)
}
public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
···
final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
if (factory != null) {
result = factory.build(context, this);
···
} else {
···
}
return result;
}
private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
ModelLoaderFactory/*T, Y*/ result = null;
if (resourceToFactories != null) {
result = resourceToFactories.get(resourceClass);
}
if (result == null) {
for (Class<? super T> registeredModelClass : modelClassToResourceFactories.keySet()) {
if (registeredModelClass.isAssignableFrom(modelClass)) {
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> currentResourceToFactories =
modelClassToResourceFactories.get(registeredModelClass);
if (currentResourceToFactories != null) {
result = currentResourceToFactories.get(resourceClass);
if (result != null) {
break;
}
}
}
}
}
return result;
}
可以看到在 getFactory() 方法中根据传入的 modelClass 从 modelClassToResourceFactories 中获取了 value
为 ModelLoaderFactory 的 Map,又根据传入的 resourceClass 从 Map 中取出 ModelLoaderFactory 对象。
那么 modelClassToResourceFactories 的数据是在哪里放入的?
在 buildModelLoader() 方法中调用了 Glide.get() 方法(见:锚点4):
public static Glide get(Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
···
glide = builder.createGlide();
···
}
}
}
return glide;
}
Glide createGlide() {
···
return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
···
register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
register(File.class, InputStream.class, new StreamFileLoader.Factory());
register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(int.class, InputStream.class, new StreamResourceLoader.Factory());
register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
register(String.class, InputStream.class, new StreamStringLoader.Factory());
register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());
···
}
public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory) {
ModelLoaderFactory<T, Y> removed = loaderFactory.register(modelClass, resourceClass, factory);
···
}
public synchronized <T, Y> ModelLoaderFactory<T, Y> register(Class<T> modelClass, Class<Y> resourceClass,
ModelLoaderFactory<T, Y> factory) {
···
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
if (resourceToFactories == null) {
resourceToFactories = new HashMap<Class/*Y*/, ModelLoaderFactory/*T, Y*/>();
modelClassToResourceFactories.put(modelClass, resourceToFactories);
}
···
return previous;
}
从锚点2、锚点3可以知道 modelClass 为 Integer.class,resourceClass 为 InputStream.class,在 Glide 的构造函数找到对应注册的 ModelLoaderFactory 为 StreamResourceLoader.Factory,所以 buildStreamModelLoader() 方法返回的是 StreamResourceLoader 对象。
同理 buildFileDescriptorModelLoader() 方法返回 FileDescriptorResourceLoader 对象。
至此,根据 ModelType,创建 DrawableRequestBuilder 和其中的 ModelLoader,为下一步加载图片做好准备的流程就分析完毕了。
在下一篇中,我们会继续分析 into() 方法:Glide 源码分析之三 into.
谢谢大家。