指定图片大小
缓存机制
指定加载格式
回调与监听
1. into()方法
2. preload()方法
3. submit()方法
4. listener()方法
图片变换
自定义模块
使用Generated API
结束语
系列文章:
=====
相关文章:
=====
Android图片加载框架最全解析(八),带你全面了解Glide 4的用法
其实在写这个系列第一篇文章的时候,Glide就推出4.0.0的RC版了。那个时候因为我一直研究的都是Glide 3.7.0版本,再加上RC版本还不太稳定,因此整个系列也都是基于3.7.0版本来写的。
而现在,Glide的最新版本已经出到了4.4.0,可以说Glide 4已经是相当成熟和稳定了。而且也不断有朋友一直在留言,想让我讲一讲Glide 4的用法,因为Glide 4相对于Glide 3改动貌似还是挺大的,学完了Glide 3再去使用Glide 4,发现根本就无法使用。
OK,那么今天就让我们用《带你全面了解Glide 4的用法》这样一篇文章,给这个Glide系列画上一个圆满的句号。
Glide 4概述
=========
刚才有说到,有些朋友觉得Glide 4相对于Glide 3改动非常大,其实不然。之所以大家会有这种错觉,是因为你将Glide 3的用法直接搬到Glide 4中去使用,结果IDE全面报错,然后大家可能就觉得Glide 4的用法完全变掉了。
其实Glide 4相对于Glide 3的变动并不大,只是你还没有了解它的变动规则而已。一旦你掌握了Glide 4的变动规则之后,你会发现大多数Glide 3的用法放到Glide 4上都还是通用的。
我对Glide 4进行了一个大概的研究之后,发现Glide 4并不能算是有什么突破性的升级,而更多是一些API工整方面的优化。相比于Glide 3的API,Glide 4进行了更加科学合理地调整,使得易读性、易写性、可扩展性等方面都有了不错的提升。但如果你已经对Glide 3非常熟悉的话,并不是就必须要切换到Glide 4上来,因为Glide 4上能实现的功能Glide 3也都能实现,而且Glide 4在性能方面也并没有什么提升。
但是对于新接触Glide的朋友而言,那就没必要再去学习Glide 3了,直接上手Glide 4就是最佳的选择了。
好了,对Glide 4进行一个基本的概述之后,接下来我们就要正式开始学习它的用法了。刚才我已经说了,Glide 4的用法相对于Glide 3其实改动并不大。在前面的七篇文章中,我们已经学习了Glide 3的基本用法、缓存机制、回调与监听、图片变换、自定义模块等用法,那么今天这篇文章的目标就很简单了,就是要掌握如何在Glide 4上实现之前所学习过的所有功能,那么我们现在就开始吧。
开始
==
要想使用Glide,首先需要将这个库引入到我们的项目当中。新建一个Glide4Test项目,然后在app/build.gradle文件当中添加如下依赖:
dependencies {
implementation ‘com.github.bumptech.glide:glide:4.4.0’
annotationProcessor ‘com.github.bumptech.glide:compiler:4.4.0’
}
注意,相比于Glide 3,这里要多添加一个compiler的库,这个库是用于生成Generated API的,待会我们会讲到它。
另外,Glide中需要用到网络功能,因此你还得在AndroidManifest.xml中声明一下网络权限才行:
就是这么简单,然后我们就可以自由地使用Glide中的任意功能了。
加载图片
====
现在我们就来尝试一下如何使用Glide来加载图片吧。比如这是一张图片的地址:
http://guolin.tech/book.png
然后我们想要在程序当中去加载这张图片。
那么首先打开项目的布局文件,在布局当中加入一个Button和一个ImageView,如下所示:
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”>
<Button
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“Load Image”
android:onClick=“loadImage”
/>
<ImageView
android:id="@+id/image_view"
android:layout_width=“match_parent”
android:layout_height=“match_parent” />
为了让用户点击Button的时候能够将刚才的图片显示在ImageView上,我们需要修改MainActivity中的代码,如下所示:
public class MainActivity extends AppCompatActivity {
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.image_view);
}
public void loadImage(View view) {
String url = “http://guolin.tech/book.png”;
Glide.with(this).load(url).into(imageView);
}
}
没错,就是这么简单。现在我们来运行一下程序,效果如下图所示:
可以看到,一张网络上的图片已经被成功下载,并且展示到ImageView上了。
你会发现,到目前为止,Glide 4的用法和Glide 3是完全一样的,实际上核心的代码就只有这一行而已:
Glide.with(this).load(url).into(imageView);
占位图
===
观察刚才加载网络图片的效果,你会发现,点击了Load Image按钮之后,要稍微等一会图片才会显示出来。这其实很容易理解,因为从网络上下载图片本来就是需要时间的。那么我们有没有办法再优化一下用户体验呢?当然可以,Glide提供了各种各样非常丰富的API支持,其中就包括了占位图功能。
顾名思义,占位图就是指在图片的加载过程中,我们先显示一张临时的图片,等图片加载出来了再替换成要加载的图片。
下面我们就来学习一下Glide占位图功能的使用方法,首先我事先准备好了一张loading.jpg图片,用来作为占位图显示。然后修改Glide加载部分的代码,如下所示:
RequestOptions options = new RequestOptions()
.placeholder(R.drawable.loading);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
没错,就是这么简单。这里我们先创建了一个RequestOptions对象,然后调用它的placeholder()方法来指定占位图,再将占位图片的资源id传入到这个方法中。最后,在Glide的三步走之间加入一个apply()方法,来应用我们刚才创建的RequestOptions对象。
不过如果你现在重新运行一下代码并点击Load Image,很可能是根本看不到占位图效果的。因为Glide有非常强大的缓存机制,我们刚才加载图片的时候Glide自动就已经将它缓存下来了,下次加载的时候将会直接从缓存中读取,不会再去网络下载了,因而加载的速度非常快,所以占位图可能根本来不及显示。
因此这里我们还需要稍微做一点修改,来让占位图能有机会显示出来,修改代码如下所示:
RequestOptions options = new RequestOptions()
.placeholder(R.drawable.loading)
.diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
可以看到,这里在RequestOptions对象中又串接了一个diskCacheStrategy()方法,并传入DiskCacheStrategy.NONE参数,这样就可以禁用掉Glide的缓存功能。
关于Glide缓存方面的内容我们待会儿会进行更详细的讲解,这里只是为了测试占位图功能而加的一个额外配置,暂时你只需要知道禁用缓存必须这么写就可以了。
现在重新运行一下代码,效果如下图所示:
可以看到,当点击Load Image按钮之后会立即显示一张占位图,然后等真正的图片加载完成之后会将占位图替换掉。
除了这种加载占位图之外,还有一种异常占位图。异常占位图就是指,如果因为某些异常情况导致图片加载失败,比如说手机网络信号不好,这个时候就显示这张异常占位图。
异常占位图的用法相信你已经可以猜到了,首先准备一张error.jpg图片,然后修改Glide加载部分的代码,如下所示:
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);
很简单,这里又串接了一个error()方法就可以指定异常占位图了。
其实看到这里,如果你熟悉Glide 3的话,相信你已经掌握Glide 4的变化规律了。在Glide 3当中,像placeholder()、error()、diskCacheStrategy()等等一系列的API,都是直接串联在Glide三步走方法中使用的。
而Glide 4中引入了一个RequestOptions对象,将这一系列的API都移动到了RequestOptions当中。这样做的好处是可以使我们摆脱冗长的Glide加载语句,而且还能进行自己的API封装,因为RequestOptions是可以作为参数传入到方法中的。
比如你就可以写出这样的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);
}
}
指定图片大小
======
实际上,使用Glide在大多数情况下我们都是不需要指定图片大小的,因为Glide会自动根据ImageView的大小来决定图片的大小,以此保证图片不会占用过多的内存从而引发OOM。
不过,如果你真的有这样的需求,必须给图片指定一个固定的大小,Glide仍然是支持这个功能的。修改Glide加载部分的代码,如下所示:
RequestOptions options = new RequestOptions()
.override(200, 100);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
仍然非常简单,这里使用override()方法指定了一个图片的尺寸。也就是说,Glide现在只会将图片加载成200*100像素的尺寸,而不会管你的ImageView的大小是多少了。
如果你想加载一张图片的原始尺寸的话,可以使用Target.SIZE_ORIGINAL关键字,如下所示:
RequestOptions options = new RequestOptions()
.override(Target.SIZE_ORIGINAL);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
这样的话,Glide就不会再去自动压缩图片,而是会去加载图片的原始尺寸。当然,这种写法也会面临着更高的OOM风险。
缓存机制
====
Glide的缓存设计可以说是非常先进的,考虑的场景也很周全。在缓存这一功能上,Glide又将它分成了两个模块,一个是内存缓存,一个是硬盘缓存。
这两个缓存模块的作用各不相同,内存缓存的主要作用是防止应用重复将图片数据读取到内存当中,而硬盘缓存的主要作用是防止应用重复从网络或其他地方重复下载和读取数据。
内存缓存和硬盘缓存的相互结合才构成了Glide极佳的图片缓存效果,那么接下来我们就来分别学习一下这两种缓存的使用方法。
首先来看内存缓存。
你要知道,默认情况下,Glide自动就是开启内存缓存的。也就是说,当我们使用Glide加载了一张图片之后,这张图片就会被缓存到内存当中,只要在它还没从内存中被清除之前,下次使用Glide再加载这张图片都会直接从内存当中读取,而不用重新从网络或硬盘上读取了,这样无疑就可以大幅度提升图片的加载效率。比方说你在一个RecyclerView当中反复上下滑动,RecyclerView中只要是Glide加载过的图片都可以直接从内存当中迅速读取并展示出来,从而大大提升了用户体验。
而Glide最为人性化的是,你甚至不需要编写任何额外的代码就能自动享受到这个极为便利的内存缓存功能,因为Glide默认就已经将它开启了。
那么既然已经默认开启了这个功能,还有什么可讲的用法呢?只有一点,如果你有什么特殊的原因需要禁用内存缓存功能,Glide对此提供了接口:
RequestOptions options = new RequestOptions()
.skipMemoryCache(true);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
可以看到,只需要调用skipMemoryCache()方法并传入true,就表示禁用掉Glide的内存缓存功能。
接下来我们开始学习硬盘缓存方面的内容。
其实在刚刚学习占位图功能的时候,我们就使用过硬盘缓存的功能了。当时为了禁止Glide对图片进行硬盘缓存而使用了如下代码:
RequestOptions options = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
调用diskCacheStrategy()方法并传入DiskCacheStrategy.NONE,就可以禁用掉Glide的硬盘缓存功能了。
这个diskCacheStrategy()方法基本上就是Glide硬盘缓存功能的一切,它可以接收五种参数:
-
DiskCacheStrategy.NONE: 表示不缓存任何内容。
-
DiskCacheStrategy.DATA: 表示只缓存原始图片。
-
DiskCacheStrategy.RESOURCE: 表示只缓存转换过后的图片。
-
DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。
-
DiskCacheStrategy.AUTOMATIC: 表示让Glide根据图片资源智能地选择使用哪一种缓存策略(默认选项)。
其中,DiskCacheStrategy.DATA对应Glide 3中的DiskCacheStrategy.SOURCE,DiskCacheStrategy.RESOURCE对应Glide 3中的DiskCacheStrategy.RESULT。而DiskCacheStrategy.AUTOMATIC是Glide 4中新增的一种缓存策略,并且在不指定diskCacheStrategy的情况下默认使用就是的这种缓存策略。
上面五种参数的解释本身并没有什么难理解的地方,但是关于转换过后的图片这个概念大家可能需要了解一下。就是当我们使用Glide去加载一张图片的时候,Glide默认并不会将原始图片展示出来,而是会对图片进行压缩和转换(我们会在稍后学习这方面的内容)。总之就是经过种种一系列操作之后得到的图片,就叫转换过后的图片。
指定加载格式
======
我们都知道,Glide其中一个非常亮眼的功能就是可以加载GIF图片,而同样作为非常出色的图片加载框架的Picasso是不支持这个功能的。
而且使用Glide加载GIF图并不需要编写什么额外的代码,Glide内部会自动判断图片格式。比如我们将加载图片的URL地址改成一张GIF图,如下所示:
Glide.with(this)
.load(“http://guolin.tech/test.gif”)
.into(imageView);
现在重新运行一下代码,效果如下图所示:
也就是说,不管我们传入的是一张普通图片,还是一张GIF图片,Glide都会自动进行判断,并且可以正确地把它解析并展示出来。
最后
文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!
由于文章篇幅问题 查看详细文章以及获取学习笔记链接:GitHub
- Android进阶学习全套手册
关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。
-
Android高级架构师进阶知识体系图
关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!
-
Android对标阿里P7学习视频
-
BATJ大厂Android高频面试题
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)** -
Android进阶学习全套手册
关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。
[外链图片转存中…(img-hrY470CU-1646395038423)]
-
Android高级架构师进阶知识体系图
关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!
[外链图片转存中…(img-D4esBxVp-1646395038424)] -
Android对标阿里P7学习视频
[外链图片转存中…(img-J2Ey2NB4-1646395038424)]
- BATJ大厂Android高频面试题
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等