一个图片加载库
Glide是一款由Bump Technologies开发的图片加载框架,使得我们可以在Android平台上以极度简单的方式加载和展示图片。
Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及自动的资源池技术。
为什么使用Glide ? TT5
多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)
生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)
高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)
高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)
(WebP(发音weppy,项目主页),是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28%的文件大小。)
Glide 的使用?
Glide.with(Context)
.load(Url)
.into(imageView);
目前,Glide最稳定版本是3.7.0
最新版本是4.2.0
使用Glide 加载一张图片
Glide.with(Context).load(Url) .into(imageView);
这一行代码进可以做非常非常多的事情了,包括加载网络上的图片、加载手机本地的图片、加载应用资源中的图片等等。
下面我们就来详细解析一下这行代码。
首先,调用Glide.with()方法用于创建一个加载图片的实例。with()方法可以接收Context、Activity或者Fragment类型的参数。也就是说我们选择的范围非常广,
不管是在Activity还是Fragment中调用with()方法,都可以直接传this。那如果调用的地方既不在Activity中也不在Fragment中,可以获取当前应用程序的ApplicationContext,
传入到with()方法当中。注意with()方法中传入的实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,
图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。
接下来看一下load()方法,这个方法用于指定待加载的图片资源。Glide支持加载各种各样的图片资源,包括网络图片、本地图片、应用资源、二进制流、Uri对象等等。
因此load()方法也有很多个方法重载,除了加载一个字符串网址之外,你还可以这样使用load()方法:
// 加载本地图片
File file = new File(getExternalCacheDir() + "/image.jpg");
Glide.with(this).load(file).into(imageView);
// 加载应用资源
int resource = R.drawable.image;
Glide.with(this).load(resource).into(imageView);
// 加载二进制流
byte[] image = getImageBytes();
Glide.with(this).load(image).into(imageView);
// 加载Uri对象
Uri imageUri = getImageUri();
Glide.with(this).load(imageUri).into(imageView);
看一下into()方法,我们希望让图片显示在哪个ImageView上,把这个ImageView的实例传进去就可以了。
现在我们来学一些Glide的扩展内容。其实刚才所学的三步走就是Glide最核心的东西,而我们后面所要学习的所有东西都是在这个三步走的基础上不断进行扩展而已。
观察刚刚加载网络图片的效果,你会发现图片需要稍微等一会图片才会显示出来。这其实很容易理解,因为从网络上下载图片本来就是需要时间的。我们可以进一步的优化一下用户体验,Glide提供了各种各样非常丰富的API支持,其中就包括了占位图功能。
顾名思义,占位图就是指在图片的加载过程中,我们先显示一张临时的图片,等图片加载出来了再替换成要加载的图片。
Glide.with(this).load(url).placeholder(R.drawable.loading).into(imageView);
我们只是在刚才的三步走之间插入了一个placeholder()方法,然后将占位图片的资源id传入到这个方法中即可。另外,这个占位图的用法其实也演示了Glide当中绝大多数API的用法,其实就是在load()和into()方法之间串接任意想添加的功能就可以了。
运行完之后很可能是根本看不到占位图效果的。因为Glide有非常强大的缓存机制,我们刚才加载那张必应美图的时候Glide
自动就已经将它缓存下来了,下次加载的时候将会直接从缓存中读取,不会再去网络下载了,因而加载的速度非常快,
所以占位图可能根本来不及显示。可以使用diskCacheStrategy()方法,并传入DiskCacheStrategy.NONE参数,这样就可以禁用掉Glide硬盘缓存功能。
除了这种加载占位图之外,还有一种异常占位图。异常占位图就是指,如果因为某些异常情况导致图片加载失败,比如说手机网络信号不好,这个时候就显示这张异常占位图。
添加一个error()方法就可以指定异常占位图了。
我们还需要再了解一下Glide另外一个强大的功能,那就是Glide是支持加载GIF图片的。而使用Glide加载GIF图并不需要编写什么额外的代码,Glide内部会自动判断图片格式。也就是说,不管我们传入的是一张普通图片,还是一张GIF图片,Glide都会自动进行判断,并且可以正确地把它解析并展示出来。
asBitmap()方法,这个方法的意思就是说这里只允许加载静态图片,如果是gif则加载第一帧。
asGif()方法,这个方法的意思就是说这里只允许加载动态图片 ,如果是非gif,则加载失败。
override()方法指定了一个图片的尺寸
使用Glide还有一个更重要的就是,完全不用担心图片内存浪费,甚至是内存溢出的问题。因为Glide从来都不会直接将图片的完整尺寸全部加载到内存中,而是用多少加载多少。Glide会自动判断ImageView的大小,然后只将这么大的图片像素加载到内存当中,帮助我们节省内存开支。
Glide的缓存设计可以说是非常先进的,考虑的场景也很周全。在缓存这一功能上,
Glide又将它分成了两个模块,一个是内存缓存,一个是硬盘缓存。
内存缓存的主要作用是防止应用重复将图片数据读取到内存当中,
硬盘缓存的主要作用是防止应用重复从网络或其他地方重复下载和读取数据。
内存缓存和硬盘缓存的相互结合才构成了Glide极佳的图片缓存效果
首先要知道,默认情况下,Glide自动就是开启内存缓存的。
也就是说,当我们使用Glide加载了一张图片之后,这张图片就会被缓存到内存当中,只要在它还没从内存中被清除之前,下次使用Glide再加载这张图片都会直接从内存当中读取,而不用重新从网络或硬盘上读取了,这样无疑就可以大幅度提升图片的加载效率。比方说你在一个RecyclerView当中反复上下滑动,RecyclerView中只要是Glide加载过的图片都可以直接从内存当中迅速读取并展示出来,从而大大提升了用户体验。
而Glide最为人性化的是,你甚至不需要编写任何额外的代码就能自动享受到这个极为便利的内存缓存功能,
因为Glide默认就已经将它开启了。
如果不想使用内存缓存的话调用skipMemoryCache()方法并传入true,就表示禁用掉Glide的内存缓存功能。
内存缓存就是LruCache算法(LeastRecentlyUsed),也叫 近期最少使用算法。它的主要算法原理就是把最近使用的
对象用强引用存储在LinkedHashMap中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。
Glide内存缓存的实现自然也是使用的LruCache算法。不过除了LruCache算法之外,Glide还结合了一种弱引用的机制,
共同完成了内存缓存功能
了解:
LruCache存储是在LinkedHashMap,因为LruCache中Lru算法的实现就是通过LinkedHashMap来实现的。LinkedHashMap继承于HashMap,它使用了一个双向链表来存储Map中的Entry顺序关系,这种顺序有两种,一种是LRU顺序,一种是插入顺序,这可以由其构造函数publicLinkedHashMap(intinitialCapacity,floatloadFactor,booleanaccessOrder)指定。
所以,对于get、put、remove等操作,LinkedHashMap除了要做HashMap做的事情,还做些调整Entry顺序链表的工作。LruCache中将LinkedHashMap的顺序设置为LRU顺序来实现LRU缓存,每次调用get(也就是从内存缓存中取图片),则将该对象移到链表的尾端。调用put插入新的对象也是存储在链表尾端,这样当内存缓存达到设定的最大值时,将链表头部的对象(近期最少用到的)移除。
这个diskCacheStrategy()方法基本上就是Glide硬盘缓存功能的一切,它可以接收四种参数:
DiskCacheStrategy.NONE: 表示不缓存任何内容。
DiskCacheStrategy.SOURCE: 表示只缓存原始图片。
DiskCacheStrategy.RESULT: 表示只缓存转换过后的图片(默认选项)。
DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。
上面四种参数的解释本身并没有什么难理解的地方,但是有一个概念大家需要了解,就是当我们使用Glide去加载一张图片的时候,Glide默认并不会将原始图片展示出来,而是会对图片进行压缩和转换(我们会在后面学习这方面的内容)。总之就是经过种种一系列操作之后得到的图片,就叫转换过后的图片。而Glide默认情况下在硬盘缓存的就是转换过后的图片,我们通过调用diskCacheStrategy()方法则可以改变这一默认行为。
硬盘缓存的实现也是使用的LruCache算法,而且Google还提供了一个现成的工具类DiskLruCache。基本的实现原理都是差不多的。
只需要通过skipMemoryCache() 跳过内存缓存
和diskCacheStrategy() 磁盘缓存策略
这两个方法就可以轻松自如地控制Glide的缓存功能了。
Glide 和 Picasso 区别
从内存开销来说
Picasso 加载图片时的内存是Glide 的两倍
原因是Picasso是加载了全尺寸的图片到内存,然后让GPU来实时重绘大小。
而Glide加载的大小和ImageView的大小是一致的,因此更小。
在这个问题上Glide完胜Picasso。因为Glide可以自动计算出任意情况下的ImageView大小。
从缓存问题来说
不管大小如何Picasso只缓存一个全尺寸的。
Glide则不同,它会为每种大小的ImageView缓存一次。尽管一张图片已经缓存了一次,但是假如你要在另外一个地方再次以不同尺寸显示,需要重新下载,调整成新尺寸的大小,然后将这个尺寸的也缓存起来。
Glide的这种方式优点是加载显示非常快。而Picasso的方式则因为需要在显示之前重新调整大小而导致一些延迟,
相对来说用户体验不太好。
Glide可以加在GIF动态图,而Picasso不能。
总结
Glide和Picasso都是非常完美的库。Glide加载图像以及磁盘缓存的方式都要优于Picasso,速度更快,
并且Glide更有利于减少OutOfMemoryError(内存不足错误)的发生,GIF动画是Glide的杀手锏。不过Picasso的图片质量更高。
如果想要更深入的了解Glide 可以去GSDN上搜郭霖的博客上边有更详细的讲解
博客地址:https://blog.csdn.net/guolin_blog