前言
在上篇中分析完了 with() 方法再来,Glide 分析之一 with.
本篇中迂苛,我們將通過 with() 方法返回的 RequestManager,來分析 load(resourceId) 的執(zhí)行過程贯要。
load
load() 方法在 RequestManager 中有8種重載镰官,結(jié)合本篇的問題,這里只分析 load(resourceId) 方法支竹。
public DrawableTypeRequest<Integer> load(Integer resourceId) {
return (DrawableTypeRequest<Integer>) fromResource().load(resourceId);(錨點(diǎn)1)
}
load(Integer resourceId) 方法內(nèi)先調(diào)用了 fromResource() 方法:
```java`
public DrawableTypeRequest<Integer> fromResource() {
return (DrawableTypeRequest<Integer>) loadGeneric(Integer.class)(錨點(diǎn)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));
}
方法內(nèi)部通過 Glide.buildStreamModelLoader() 和 Glide.buildFileDescriptorModelLoader() 方法創(chuàng)建兩個(gè) ModelLoader 對(duì)象用于圖片加載旋廷。
這兩個(gè)方法會(huì)根據(jù)傳入?yún)?shù),返回相應(yīng)的 ModelLoader 實(shí)現(xiàn)類礼搁。本例中饶碘,buildStreamModelLoader() 返回 StreamResourceLoader,buildFileDescriptorModelLoader() 返回 FileDescriptorResourceLoader馒吴,這兩個(gè)方法在最后有詳細(xì)分析熊镣。
loadGeneric() 方法最后創(chuàng)建了 DrawableTypeRequest 對(duì)象,并返回募书。
錨點(diǎn)2處執(zhí)行完之后繼續(xù)調(diào)用 signature() 方法绪囱,標(biāo)記了一個(gè) Key,然后把 DrawableTypeRequest<Integer> 對(duì)象返回出去莹捡。
上一層拿到 DrawableTypeRequest<Integer> 對(duì)象后調(diào)用了它的 load(resourceId) 方法(見:錨點(diǎn)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> 對(duì)象。
至此篮赢,load() 方法主線流程就分析完畢了齿椅,接下來會(huì)繼續(xù)分析 Glide.buildStreamModelLoader() 方法是如何返回 ModelLoader 的琉挖。
Glide.buildStreamModelLoader()
public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
return buildModelLoader(modelClass, InputStream.class, context);(錨點(diǎn)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);(錨點(diǎn)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() 方法中根據(jù)傳入的 modelClass 從 modelClassToResourceFactories 中獲取了 value
為 ModelLoaderFactory 的 Map,又根據(jù)傳入的 resourceClass 從 Map 中取出 ModelLoaderFactory 對(duì)象涣脚。
那么 modelClassToResourceFactories 的數(shù)據(jù)是在哪里放入的示辈?
在 buildModelLoader() 方法中調(diào)用了 Glide.get() 方法(見:錨點(diǎn)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;
}
從錨點(diǎn)2、錨點(diǎn)3可以知道 modelClass 為 Integer.class遣蚀,resourceClass 為 InputStream.class矾麻,在 Glide 的構(gòu)造函數(shù)找到對(duì)應(yīng)注冊(cè)的 ModelLoaderFactory 為 StreamResourceLoader.Factory,所以 buildStreamModelLoader() 方法返回的是 StreamResourceLoader 對(duì)象芭梯。
同理 buildFileDescriptorModelLoader() 方法返回 FileDescriptorResourceLoader 對(duì)象险耀。
至此,根據(jù) ModelType玖喘,創(chuàng)建 DrawableRequestBuilder 和其中的 ModelLoader甩牺,為下一步加載圖片做好準(zhǔn)備的流程就分析完畢了。
在下一篇中累奈,我們會(huì)繼續(xù)分析 into() 方法:Glide 源碼分析之三 into.
謝謝大家贬派。