安卓项目实战之:帮你从Glide3过渡到Glide4的完美攻略

Glide4:Glide3的优化版

相比于Glide 3 而言,Glide4并不能算是有什么突破性的升级,而更多的是一些API工整方面的优化,相比于Glide3的API,Glide4进行了更加科学合理的调整,使得易读性,易写性,可扩展性等方面都有了不错的提升,但如果你已经对Glide3非常熟悉的话,并不是就必须要切换到Glide4上面来,因为Glide4能实现的功能Glide3也能实现,而且Glide4在性能方面也并没有什么提升,但是对于刚接触Glide的朋友而言,直接上手Glide4是最佳选择。

当然对于已经熟练掌握Glide3用法的朋友,如果想迁移到Glide4上来也是一件很容易的事,因为改动虽然有,但是并不大,而且改的也仅仅是表象,底层实现基本没变,只要看完本篇即可成功完成过渡。

本文重新排版,参考自博客: https://blog.csdn.net/guolin_blog/article/details/78582548

添加依赖

dependencies {
    compile 'com.github.bumptech.glide:glide:4.7.1'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}

添加依赖时如果报错,尝试解决如下,在Project的build.gradle文件中添加仓库:

allprojects {
    repositories {
        jcenter()
        //需要添加的部分
        maven { url "https://maven.google.com"}
    }
}

在添加依赖时,相比于Glide 3,这里多添加了一个compiler的库,这个库是用于生成Generated API的,有了它我们就可以完全使用Glide3的语法来书写代码了,不同的是需要使用GlideApp去调用,具体用法见后文。

和Glide 3的相同点

Glide4 和Glide3一样,核心代码就只有下面这一行:

Glide.with(this).load(url).into(imageView);

和Glide 3的不同点

1,RequestOptions对象的引入

在使用Glide3的时候我们知道,可以设置图片加载的默认占位图,异常占位图,以及指定加载的图片宽高,指定缓存策略,设置图片变换等,在Glide3中我们的写法是这样的:

   Glide.with(this)
        .load(url)
        .placeholder(R.drawable.loading)  // 占位图
        .error(R.drawable.error)          // 异常占位图
        .skipMemoryCache(true)            // true表示禁用内存缓存
        .diskCacheStrategy(DiskCacheStrategy.NONE) // 禁用磁盘缓存 
        .override(Target.SIZE_ORIGINAL)   // 指定加载图片的原始尺寸
     // .transforms(...);
        .circleCrop()                     // 图片变换功能:使用内置的圆角变换效果,本质也是调用了.transforms(...)方法,如果要自定义变换就必须实现.transforms(...)去指定了,或使用图片变换开源库glide-transformations
        .into(imageView);

可以发现在Glide 3当中,像placeholder()、error()、diskCacheStrategy()等等一系列的API,都是直接串联在Glide三步走方法中使用的。

而在Glide 4中引入了一个RequestOptions对象,将这一系列的API都移动到了RequestOptions当中,使用如下:

RequestOptions options = new RequestOptions()
        .placeholder(R.drawable.ic_launcher_background)
        .error(R.drawable.error)
        .diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(this)
     .load(url)
     .apply(options)
     .into(imageView);

Glide4的使用只要在Glide的三步走之间加入一个apply()方法,来应用我们刚才创建的RequestOptions对象即可。

Glide 4这样做的好处是可以使我们摆脱冗长的Glide加载语句,而且还能进行自己的API封装,比如你就可以写出这样的Glide加载工具类:

public class GlideUtil {

    public static void load(Context context, String url, ImageView imageView, RequestOptions options) {
          Glide.with(context)
               .load(url)
               .apply(options)
               .into(imageView);
    }
    
}

2,指定图片加载的格式(注意Glide4新版本中asBitmap调用的位置改动)

一般情况下我们使用核心代码加载图片时,不管我们传入的是一张普通图片,还是一张GIF图片,Glide都会自动进行判断,并且可以正确地把它解析并展示出来。
指定加载的图片格式是静态图片,不需要Glide帮我们判断图片格式:

Glide.with(this)
     .asBitmap()
     .load("http://guolin.tech/test.gif")
     .into(imageView);

这样指定之后,如果传入的是GIF图片,那么只会显示第一帧。
此外注意:在Glide 3中的语法是先load()再asBitmap()的,而在Glide 4中是先asBitmap()再load()的。

类似地,既然我们能强制指定加载静态图片,就也能强制指定加载动态图片,对应的方法是asGif()。而Glide 4中又新增了asFile()方法和asDrawable()方法,分别用于强制指定文件格式的加载和Drawable格式的加载,用法都比较简单,就不再进行演示了。

3,回调与监听的写法和Glide3基本一致

例如下面简单的示例,更多的用法可参考:安卓项目实战之Glide高手养成(三):Glide的回调与监听

SimpleTarget<Drawable> simpleTarget = new SimpleTarget<Drawable>() {
    @Override
    public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
        imageView.setImageDrawable(resource);
    }
};

public void loadImage(View view) {
    Glide.with(this)
         .load("http://guolin.tech/book.png")
         .into(simpleTarget);
}

自定义模块

自定义模块功能可以将更改Glide配置,替换Glide组件等操作独立出来,使得我们能轻松地对Glide的各种配置进行自定义,并且又和Glide的图片加载逻辑没有任何交集,这也是一种低耦合编程方式的体现。下面我们就来学习一下自定义模块要如何实现。
首先定义一个我们自己的模块类,并让它继承自AppGlideModule,如下所示:

@GlideModule
public class MyAppGlideModule extends AppGlideModule {

   // 用来更改Glide配置时使用
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {

    }

    // 用于替换Glide组件时使用
    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {

    }

}

可以看到,在MyAppGlideModule类当中,我们重写了applyOptions()和registerComponents()方法,这两个方法分别就是用来更改Glide配置以及替换Glide组件的。

注意在MyAppGlideModule类在上面,我们加入了一个@GlideModule的注解,这是Gilde 4和Glide 3最大的一个不同之处。在Glide 3中,我们定义了自定义模块之后,还必须在AndroidManifest.xml文件中去注册它才能生效,而在Glide 4中是不需要的,因为@GlideModule这个注解已经能够让Glide识别到这个自定义模块了。

这样的话,我们就将Glide自定义模块的功能完成了。后面只需要在applyOptions()和registerComponents()这两个方法中加入具体的逻辑,就能实现更改Glide配置或者替换Glide组件的功能了。详情还是请参考 Android图片加载框架最全解析(六),探究Glide的自定义模块功能 这篇文章,这里就不再展开讨论了。

支持延续Glide3一模一样的用法:使用Generated API

Generated API是Glide 4中全新引入的一个功能,它的工作原理是使用注解处理器 (Annotation Processor) 来生成出一个API,在Application模块中可使用该流式API一次性调用到RequestBuilder,RequestOptions和集成库中所有的选项。

简单点说就是Glide 4仍然给我们提供了一套和Glide 3一模一样的流式API接口。毕竟有些人还是觉得Glide 3的API更好用一些,比如说我。

Generated API对于熟悉Glide 3的朋友来说那是再简单不过了,基本上就是和Glide 3一模一样的用法,只不过需要把Glide关键字替换成GlideApp关键字,如下所示:

GlideApp.with(this)
        .load(url)
        .placeholder(R.drawable.loading)
        .error(R.drawable.error)
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .override(Target.SIZE_ORIGINAL)
        .circleCrop()
        .into(imageView);

上面的代码和我们文章开始在Glide3中使用的代码除了变成了使用GlideApp调用外其他的完全一致。

但是我们需要先通过操作生成GlideApp这个类:
GlideApp这个类是通过编译时注解自动生成的,首先确保你的代码中有一个自定义的模块,并且给它加上了@GlideModule注解,也就是我们在上一节所讲的内容。然后在Android Studio中点击菜单栏Build -> Rebuild Project,GlideApp这个类就会自动生成了。

当然,Generated API所能做到的并不只是这些而已,它还可以对现有的API进行扩展,定制出任何属于你自己的API。

下面我来具体举个例子,比如说我们要求项目中所有图片的缓存策略全部都要缓存原始图片,那么每次在使用Glide加载图片的时候,都去指定diskCacheStrategy(DiskCacheStrategy.DATA)这么长长的一串代码,确实是让人比较心烦。这种情况我们就可以去定制一个自己的API了。

定制自己的API需要借助@GlideExtension和@GlideOption这两个注解。创建一个我们自定义的扩展类,代码如下所示:

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {

    }

    @GlideOption
    public static void cacheSource(RequestOptions options) {
        options.diskCacheStrategy(DiskCacheStrategy.DATA);
    }

}

这里我们定义了一个MyGlideExtension类,并且给加上了一个@GlideExtension注解,然后要将这个类的构造函数声明成private,这都是必须要求的写法。

接下来就可以开始自定义API了,这里我们定义了一个cacheSource()方法,表示只缓存原始图片,并给这个方法加上了@GlideOption注解。注意自定义API的方法都必须是静态方法,而且第一个参数必须是RequestOptions,后面你可以加入任意多个你想自定义的参数。

在cacheSource()方法中,我们仍然还是调用的diskCacheStrategy(DiskCacheStrategy.DATA)方法,所以说cacheSource()就是一层简化API的封装而已。

然后在Android Studio中点击菜单栏Build -> Rebuild Project,神奇的事情就会发生了,你会发现你已经可以使用这样的语句来加载图片了:

GlideApp.with(this)
        .load(url)
        .cacheSource()
        .into(imageView);

有了这个强大的功能之后,我们使用Glide就能变得更加灵活了。

解锁Glide 4在项目里面使用的新姿势

1,首先当然是添加依赖了,省略…
2,然后我们自定义一个CusGlideApp,来继承AppGlideModule,写法如下:

@GlideModule
public final class CusGlideApp extends AppGlideModule {

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        super.applyOptions(context, builder);
    }
}

注意:别忘记要添加@GlideModule注解。
3,然后在Android Studio中点击菜单栏Build -> Rebuild Project,GlideApp这个类就会自动生成了。
4,定义Glide使用的工具类GlideUtil,代码如下:

public class GlideUtil {

    public static void loadImage(Context context, Object imgUrl, SimpleTarget<Drawable> target) {
        GlideApp.with(context)
                .load(imgUrl)
                .placeholder(R.drawable.img_viewer_placeholder)
                .error(R.drawable.img_viewer_placeholder)
                .into(target);
    }

    public static void loadImage(Context context, Object imgUrl, ImageView imageView) {
        GlideApp.with(context)
                .load(imgUrl)
                .placeholder(R.drawable.img_viewer_placeholder)
                .error(R.drawable.img_viewer_placeholder)
                .into(imageView);
    }
    // 注意和上面的区别,一个是Glide3写法(需配合GlideApp使用)一个是Glide4写法
     public static void load(Context context, String url, ImageView imageView, RequestOptions options) {
          Glide.with(context)
               .load(url)
               .apply(options)
               .into(imageView);
     }
}

这样GlideUtil的工具类就创建完成了,以后加载图片就只要调用一个方法就ok了。


之前Glide3系列文章提到的所有的内容均适用于Glide4,只是在调用语法规则和书写格式上有略微的区别而已,更多使用请参考Glide系列文章

猜你喜欢

转载自blog.csdn.net/gpf1320253667/article/details/84307298