美文网首页工作生活
Android 图片加载(四)Glide自定义模块

Android 图片加载(四)Glide自定义模块

作者: 怡红快绿 | 来源:发表于2019-07-10 14:23 被阅读0次

Glide内部HTTP通讯组件的底层实现是基于HttpUrlConnection来进行定制的。但是HttpUrlConnection的可扩展性比较有限,因此我们今天介绍如何将Glide中的HTTP通讯组件替换成OkHttp。

一、前言

Glide v3中,当我们创建好一个自定义模块之后,还必须在AndroidManifest.xml文件中注册它才能生效。随着Glide框架的不断优化,在Glide v4中我们只需要使用@GlideModule这个注解就能够让Glide轻轻松松识别到我们创建的自定义模块。

Glide已经更新到4.9.0,本文就不去介绍Glide v3中的自定义模块,只介绍Glide v4中如何自定义模块。当然如果感兴趣的话也可以学习一下旧版本中的自定义模块,推荐一篇非常优秀的文章

二、自定义模块基本使用

Glide v4是使用注解机制来完成自定义模块的创建工作的,因此在工作正式开始之前我们还需要引入一些必需的依赖库。

1、添加对 Glide 的注解解析器的依赖和对OkHttp集成库的依赖

implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.8.0'

2、创建自定义模块

从Glide v4开始,Glide框架引入了注解机制,自定义模块的创建也变得非常简单。

  1. 首先要实现AppGlideModule 类。
  2. 接着给上述实现添加@GlideModule注解。
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        
    }

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        
    }
}
  1. 最后,你应该在你的 proguard.cfg 中 keep 住你的 AppGlideModule 实现。
-keep public class  extends com.bumptech.glide.module.AppGlideModule
-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl

这样模块类就创建完成了。我们可以看到上述代码中有两个需要重写的方法applyOptions和registerComponents,那么这两个方法的作用是什么呢?

applyOptions

认真阅读过上一篇文章的同学对applyOptions()这个方法应该比较熟悉了,它在应用程序选项一节中多次出现过,它的主要职责就是配置对大部分应用程序合理的默认选项。

假如有这样一个场景:我希望Glide在加载图片的时候禁止任何缓存操作。为了满足这个条件,那么我应用中的图片加载语句可能是类似下面这样的:

Glide.with(this)
        .asDrawable()
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .load(IMAGE_URL)
        .into(imageView);

一直重复编写这么长的语句显然是不理智的,此时我们就可以在applyOptions方法中配置所有请求的默认选项:

@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
    RequestOptions requestOptions = new RequestOptions()
            .skipMemoryCache(true) //不使用内存缓存
            .diskCacheStrategy(DiskCacheStrategy.NONE);  //原图和缩略图都不进行磁盘缓存
    builder.setDefaultRequestOptions(requestOptions);
}

这样所有的图片加载请求在默认情况下就不会进行缓存操作了,我们的图片加载语句也会变得很简单:

Glide.with(this)
        .load(IMAGE_URL)
        .into(imageView);
registerComponents

registerComponents,顾名思义,这个方法的作用就是注册组件,这也是这一篇文章要介绍的重点内容。

假如有一天产品经理提出了一个新功能,需要显示图片的加载进度,由于Glide内部是基于HttpUrlConnection实现网络通讯的,我们在它的基础之上无法实现监听下载进度的功能,因此我们就需要用OkHttp替换HttpUrlConnection。

@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addInterceptor(new ProgressInterceptor());  //拦截器
    OkHttpClient okHttpClient = builder.build();
    registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
}

这样我们就成功地用OkHttp替换掉HttpUrlConnection来进行网络通讯。

Registry类中不仅定义了replace()方法,还有prepend()append()方法,它们可以用于设置 Glide 尝试每个ModelLoaderResourceDecoder之间的顺序,我们可以根据实际需求选用。

假如你的 ModelLoader 或者 ResourceDecoder 在某个地方失败了,这时候你想将已有的数据交由 Glide 的默认行为来处理,可以使用 prepend()prepend() 将确保你的 ModelLoaderResourceDecoder 先于之前注册的其他组件并被首先执行。如果你的 ModelLoader 或者 ResourceDecoder 从其 handles() 方法中返回了一个 false 或失败,所有其他的 ModelLoaderResourceDecoder 将以它们被注册的顺序执行,一次一个,作为一种回退方案。

要处理新的数据类型或提供一个到 Glide 默认行为的回退,使用 append()append() 将确保你的 ModelLoaderResourceDecoder 仅在 Glide 的默认组件被尝试后才会被调用。 如果你正在尝试处理 Glide 的默认组件能处理的某些子类型 (例如一些特定的 Uri 授权或子类型),你可能需要使用 prepend() 来确保 Glide 的默认组件不会在你的定制组件之前加载。

要完全替换 Glide 的默认行为并确保它绝不运行,请使用 replace()replace() 将移除所有处理给定模型和数据类的 ModelLoaders,并添加你的 ModelLoader 来代替。 replace() 在使用库(例如 OkHttp 或 Volley)替换掉 Glide 的网络逻辑时尤其有用,这种时候你会希望确保仅 OkHttp 或 Volley 被调用。


参考链接

相关文章

网友评论

    本文标题:Android 图片加载(四)Glide自定义模块

    本文链接:https://www.haomeiwen.com/subject/oehthctx.html