GenericLoaderFactory
这个类是个静态工厂
使用这个2个容器 , 把 register 工厂和 build modelLoader 给缓存起来 ;
private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/>> modelClassToResourceFactories =
new HashMap<Class, Map<Class, ModelLoaderFactory>>();
private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoader/*T, Y*/>> cachedModelLoaders =
new HashMap<Class, Map<Class, ModelLoader>>();
public synchronized <T, Y> ModelLoaderFactory<T, Y> register(Class<T> modelClass, Class<Y> resourceClass,
ModelLoaderFactory<T, Y> factory) {
cachedModelLoaders.clear();
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);
}
ModelLoaderFactory/*T, Y*/ previous = resourceToFactories.put(resourceClass, factory);
if (previous != null) {
// This factory may be being used by another model. We don't want to say it has been removed unless we
// know it has been removed for all models.
for (Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> factories : modelClassToResourceFactories.values()) {
if (factories.containsValue(previous)) {
previous = null;
break;
}
}
}
return previous;
}
public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
if (result != null) {
// We've already tried to create a model loader and can't with the currently registered set of factories,
// but we can't use null to demonstrate that failure because model loaders that haven't been requested
// yet will be null in the cache. To avoid this, we use a special signal model loader.
if (NULL_MODEL_LOADER.equals(result)) {
return null;
} else {
return result;
}
}
final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
if (factory != null) {
result = factory.build(context, this);
cacheModelLoader(modelClass, resourceClass, result);
} else {
// We can't generate a model loader for the given arguments with the currently registered set of factories.
cacheNullLoader(modelClass, resourceClass);
}
return result;
}
在glide的构造方法里 把需要的参数存起来了
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());
这个register 方法会吧数据给存到GenericLoaderFactory类里
public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory) {
ModelLoaderFactory<T, Y> removed = loaderFactory.register(modelClass, resourceClass, factory);
if (removed != null) {
removed.teardown();
}
}
默认是按照这个接口默认进行解耦的
/**
*
* @param <T> GlideUrl.class
* @param <Y> InputStream.class
* @param ModelLoader HttpUrlGlideUrlLoader
* @param DataFetcher HttpUrlFetcher
*/
public interface ModelLoaderFactory<T, Y> {
ModelLoad<T, Y> build();
interface ModelLoad<T, Y> {
DataFetcher<Y> getResourceFetcher(T model);
}
interface DataFetcher<T> {
T loadData();
}
}
我们来看下 HttpUrlGlideUrlLoader 这个类 , 在glide构造方法里,register时 , 调用了HttpUrlGlideUrlLoader.Factory()
public class HttpUrlGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {
private final ModelCache<GlideUrl, GlideUrl> modelCache;
/**
* The default factory for {@link com.bumptech.glide.load.model.stream.HttpUrlGlideUrlLoader}s.
*/
public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {
private final ModelCache<GlideUrl, GlideUrl> modelCache = new ModelCache<GlideUrl, GlideUrl>(500);
@Override
public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) {
return new HttpUrlGlideUrlLoader(modelCache);
}
@Override
public void teardown() {
// Do nothing.
}
}
public HttpUrlGlideUrlLoader() {
this(null);
}
public HttpUrlGlideUrlLoader(ModelCache<GlideUrl, GlideUrl> modelCache) {
this.modelCache = modelCache;
}
@Override
public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {
// GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time spent parsing urls.
GlideUrl url = model;
if (modelCache != null) {
url = modelCache.get(model, 0, 0);
if (url == null) {
modelCache.put(model, 0, 0, model);
url = model;
}
}
return new HttpUrlFetcher(url);
}
}