Hello Glide

Glide是什么?
一个图片加载库
Glide是一款由Bump Technologies开发的图片加载框架,使得我们可以在Android平台上以极度简单的方式加载和展示图片。
Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管(decode pipeline),以及自动的资源池技术。

为什么使用Glide ?
多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)
生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)
高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)
高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)

(WebP(发音weppy,项目主页),是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28%的文件大小。)

Glide 的使用

目前,Glide最稳定版本是3.7.0 。最新版本是4.2.0     

使用:

(一)先导入依赖    implementation 'com.github.bumptech.glide:glide:3.7.0'(看自己的需求)

(二)最基本的加载一张网络图片     Glide.with(Context).load(Url) .into(imageView);
这一行代码进可以做非常非常多的事情了,包括加载网络上的图片、加载手机本地的图片、加载应用资源中的图片等等。
下面我们就来详细解析一下这行代码。

(1)调用Glide.with()方法用于创建一个加载图片的实例。

           with()方法可以接收Context、Activity或者Fragment类型的参数。也就是说我们选择的范围非常广,
         不管是在Activity还是Fragment中调用with()方法,都可以直接传this。那如果调用的地方既不在Activity中也不在          Fragment中,可以获取当前应用程序的ApplicationContext,传入到with()方法当中。注意with()方法中传入的实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,
图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。

(2)接下来看一下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);

(3)into()方法,

      我们希望让图片显示在哪个ImageView上,把这个ImageView的实例传进去就可以了。

现在我们来学一些Glide的扩展内容。其实刚才所学的三步走就是Glide最核心的东西,而我们后面所要学习的所有东西都是在这个三步走的基础上不断进行扩展而已。

一、

我们会发现使用上面的方法在网络慢的情况下图片需要稍微等一会图片才会显示出来,有时候甚至是一直处于空白状态。这其实很容易理解,因为从网络上下载图片本来就是需要时间的。我们可以进一步的优化一下用户体验,Glide提供了各种各样非常丰富的API支持,其中就包括了占位图功能

顾名思义,占位图就是指在图片的加载过程中,我们先显示一张临时的图片,等图片加载出来了再替换成要加载的图片。
Glide.with(this).load(url).placeholder(R.drawable.loading).into(imageView);
除了这种加载占位图之外,还有一种异常占位图。异常占位图就是指,如果因为某些异常情况导致图片加载失败,比如说手机网络信号不好,这个时候就显示这张异常占位图。
错误占位符可以从字面的意思来理解什么是错误的占位符,也就是我们 的APP从一个网站去加载一张图片的时候,返回时告诉我们获取失败,这时就用到了错误占位符来显示图片,如果想进行一些其他操作,可自己决定。.error()。

二、

Glide另外一个强大的功能,那就是Glide是支持加载GIF图片的。而使用Glide加载GIF图并不需要编写什么额外的代码,Glide内部会自动判断图片格式。也就是说,不管我们传入的是一张普通图片,还是一张GIF图片,Glide都会自动进行判断,并且可以正确地把它解析并展示出来。

asBitmap()方法,这个方法的意思就是说这里只允许加载静态图片,如果是gif则加载第一帧。
asGif()方法,这个方法的意思就是说这里只允许加载动态图片 ,如果是非gif,则加载失败。
override()方法指定了一个图片的尺寸

三、

Glide还有一个更重要的就是,完全不用担心图片内存浪费,甚至是内存溢出的问题。因为Glide从来都不会直接将图片的完整尺寸全部加载到内存中,而是用多少加载多少。Glide会自动判断ImageView的大小,然后只将这么大的图片像素加载到内存当中,帮助我们节省内存开支。

四、对图片进行裁剪、模糊、滤镜等处理:

         需要导包      compile 'jp.wasabeef:glide-transformations:2.0.0'

    //圆形裁剪(圆形图片是将其裁剪,而并非将原有的图片缩放后显示)
    Glide.with(this)
        .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
        .bitmapTransform(new CropCircleTransformation(this))
        .into(iv_0);
    //圆角处理
    Glide.with(this)
        .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
        .bitmapTransform(new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL))
        .into(iv_0);
    //灰度处理
    Glide.with(this)
        .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
        .bitmapTransform(new GrayscaleTransformation(this))
        .into(iv_0);

      //图片的裁剪

     Glide.with(this)
         .load(url)
         .bitmapTransform(new CropCircleTransformation(this))
         .into(iv_0);

//颜色的转换
       Glide.with(this)
          .load(url)
          .bitmapTransform(new ColorFilterTransformation(this, 0x7900CCCC))
          .into((iv_0);

 

//模糊处理BlurTransformation

// 使用构造方法 BlurTransformation(Context context, int radius, int sampling)
  // radius : 离散半径/模糊度(单参构造器 - 默认25)
  // sampling : 取样(单参构造器 - 默认1) 如果取2,横向、纵向都会每两个像素点取一个像素点(即:图片宽高变为原来一半)
  Glide.with(this)
          .load(url)
          .bitmapTransform(new BlurTransformation(this, 100, 2))
          .into(iv_0);

 

//GPU过滤(需要依赖GPUImage库           compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.3.0'  )

    ToonFilterTransformation (卡通滤波器)

    // 使用构造方法 ToonFilterTransformation(Context context, float threshold, float quantizationLevels)
      // threshold :阀值(单参构造器 - 默认0.2F)影响色块边界的描边效果
      // quantizationLevels :量化等级(单参构造器 - 默认10.0F)影响色块色彩
      Glide.with(this)
              .load(url)
              .bitmapTransform(new ToonFilterTransformation(this, 0.2F, 10F))
              .into(iv_0);

………………………………

五、

或许有的读者会发现当我们第二次运行项目的时候运行完之后很可能是根本看不到占位图效果的。因为Glide有非常强大的缓存机制,我们刚才加载那张必应美图的时候Glide自动就已经将它缓存下来了,下次加载的时候将会直接从缓存中读取,不会再去网络下载了,因而加载的速度非常快,所以占位图可能根本来不及显示。而Glide最为人性化的是,你甚至不需要编写任何额外的代码就能自动享受到这个极为便利的内存缓存功能,因为Glide默认就已经将它开启了。

Glide的缓存设计可以说是非常先进的,考虑的场景也很周全。在缓存这一功能上,
Glide又将它分成了两个模块,一个是内存缓存,一个是硬盘缓存

内存缓存的主要作用是防止应用重复将图片数据读取到内存当中,
硬盘缓存的主要作用是防止应用重复从网络或其他地方重复下载和读取数据。

内存缓存和硬盘缓存的相互结合才构成了Glide极佳的图片缓存效果

首先要知道,默认情况下,Glide自动就是开启内存缓存的。
也就是说,当我们使用Glide加载了一张图片之后,这张图片就会被缓存到内存当中,只要在它还没从内存中被清除之前,下次使用Glide再加载这张图片都会直接从内存当中读取,而不用重新从网络或硬盘上读取了,这样无疑就可以大幅度提升图片的加载效率。比方说你在一个RecyclerView当中反复上下滑动,RecyclerView中只要是Glide加载过的图片都可以直接从内存当中迅速读取并展示出来,从而大大提升了用户体验。

Glide在缓存Resource使用三层缓存,包括:

    一级缓存:缓存被回收的资源,使用LRU算法(Least Frequently Used,最近最少使用算法)。当需要再次使用到被回收的资源,直接从内存返回。
    二级缓存:使用弱引用缓存正在使用的资源。当系统执行gc操作时,会回收没有强引用的资源。使用弱引用缓存资源,既可以缓存正在使用的强引用资源,也不阻碍系统需要回收无引用资源。
    三级缓存:磁盘缓存。网络图片下载成功后将以文件的形式缓存到磁盘中。

 

内存缓存就是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()  传入DiskCacheStrategy.NONE参数,这样就可以禁用掉Glide硬盘缓存功能。
这两个方法就可以轻松自如地控制Glide的缓存功能了。

 

六、最后我们简单的对比Glide 和 Picasso 区别

从内存开销来说
Picasso 加载图片时的内存是Glide 的两倍
原因是Picasso是加载了全尺寸的图片到内存,然后让GPU来实时重绘大小。
而Glide加载的大小和ImageView的大小是一致的,因此更小。
在这个问题上Glide完胜Picasso。因为Glide可以自动计算出任意情况下的ImageView大小。

从缓存问题来说
不管大小如何Picasso只缓存一个全尺寸的。
Glide则不同,它会为每种大小的ImageView缓存一次。尽管一张图片已经缓存了一次,但是假如你要在另外一个地方再次以不同尺寸显示,需要重新下载,调整成新尺寸的大小,然后将这个尺寸的也缓存起来。
Glide的这种方式优点是加载显示非常快。
而Picasso的方式则因为需要在显示之前重新调整大小而导致一些延迟,相对来说用户体验不太好。

Glide可以加在GIF动态图,而Picasso不能。

 

 

 

(由于Glide的强大功能,小媛暂且整理这些,若存在bug,欢迎大神们积极砸砖,共同学习,一起进步)

 

 

 

 

 

 

 

 

 

 

 

 

 
                

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值