Glide 使用OkHttp加载图片源码分析

在Glide中使用OkHttp加载图片,首先要注册,下面是代码:
Glide.get(getApplicationContext()).register(GlideUrl.class, InputStream.class,
                new OkHttpUrlLoader.Factory(getGlideOkHttpClient()));
经过这样注册后,Glide就可以通过OkHttp加载图片。Glide怎么样经过OkHttp加载图片值得探究一下。
先看一下Glide.get()中做了什么。
public static Glide get(Context context) {
        if (glide == null) {
            synchronized (Glide.class) {
                if (glide == null) {
                    Context applicationContext = context.getApplicationContext();
                    List<GlideModule> modules = new ManifestParser(applicationContext).parse();
                    GlideBuilder builder = new GlideBuilder(applicationContext);
                    for (GlideModule module : modules) {
                        module.applyOptions(applicationContext, builder);
                    }
                    glide = builder.createGlide(); (1)
                    for (GlideModule module : modules) {
                        module.registerComponents(applicationContext, glide); (2)
                    }
                }
            }
        }
        return glide;
    }
主要关注(1)和(2)这两个地方。
在builder.createGlide()中
Glide createGlide() {
       /..../ 
        return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
  }
createGlide初始化了内存缓存、bitmap对象池等等,最主要的是构造Glide全局单例。
Glide初始化了各种东西,
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());
        /... 省略.../
    }
register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());很关键,通过Http加载图片,这是Glide的Http加载。要使用Okhttp加载就得替换掉Glide自身Http加载。

这就到了Glide.get(getApplicationContext()). register(GlideUrl.class, InputStream.class,
new OkHttpUrlLoader.Factory(getGlideOkHttpClient()));的 register
看下 register:
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();
        }
    }
调用了loaderFactory.register,loaderFactory在new Glide中初始化,看一下 loaderFactory.register
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;
    }
比较关键就是加粗的这几行代码,首先从 modelClassToResourceFactories中查找 modelClass(当前为 GlideUrl.class,在前面new Glide()的时候已经注册过key为GlideUrl.class的ModelLoaderFactory(Glide自带的HttpLoader),所以查找到的 resourceToFactories不为空,
然后用 Okhttpfactory替换 Glide自带的 Http,ModelLoaderFactory/*T, Y*/ previous = resourceToFactories.put(resourceClass, factory);。
就这样完成了 OkHttp加载图片的替换





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值