Glide原理

1.Glide是什么?

Glide是Google在2014的IO大会发布一款图片处理框架,是目前android领域比较成熟的一款,也是Google官方推荐的图片处理框架,主要支持网络图片、二进制流、drawable资源、本地图片显示,还支持本地视频显示。

2. Glide 基本用法

1.在app级别下面配置gradle

dependencies {
	implementation 'com.github.bumptech.glide:glide:4.11.0' //图片加载框架
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'    //图片加载框架注解处理器
}

2.通过Glide类进行一个链式调用

Glide.with(getApplicationContext()).load(imageurl).into(imageview);

with()

在使用过程中尽量要传入Applicaiton、Activity 、Fragment等类型的参数,因为glide加载图片的请求会与该参数的生命周期绑定在一起,如果onPaush时候,Glide就会暂停加载,重新onResume之后,又会继续加载。

load()

支持网络图片网址、二进制流、drawable资源、本地图片的传入。

crossFade

这是开启显示淡入淡出的动画

override

如果获取的网络图片过大,我们通过它进行一个大小的裁剪,传入width和height参数进行宽高裁剪。

diskCacheStrategy

磁盘缓存的设置,默认Glide会开启的。

DiskCacheStrategy.NONE 什么都不缓存

DiskCacheStrategy.SOURCE 只缓存全尺寸图

DiskCacheStrategy.RESULT 只缓存最终的加载图

DiskCacheStrategy.ALL 缓存所有版本图(默认行为)

Glide 不仅缓存了全尺寸的图,还会根据 ImageView 大小所生成的图也会缓存起来。比如,请求一个 800x600 的图加载到一个 400x300 的 ImageView 中,Glide默认会将这原图还有加载到 ImageView 中的 400x300 的图也会缓存起来。

error

这里的设置是当加载图片出现错误时,显示的图片。

placeholder

图片加载完成之前显示的占位图。

into()

一般传 ImageView 。

3. Glide源码原理分析

With
当上下文对象传入的是非全局context,如果glide运行在非UI线程,使用全局上下文,如果glide在UI线程加载图片,因为activity的生命周期和UI线程并不完全同步,所以glide无法准确得知寄存体的生命周期, 因此glide底层创建出一个不可见fragment,而fragment的生命周期和activity同步,所以当activity ondestory的时候,停止glide图片加载。
如果是全局上下文,那么glide加载图片跟随application的生命周期。

缓存:glide支持默认内存缓存,当然根据实际需求可以关闭内存缓存。本地缓存需要手动设置,总共有四个缓存类型,

  • all:缓存资源和处理结果;
  • source:只缓存资源;
  • result:只缓存处理结果图;
  • none:不进行本地缓存;

缓存采用lrucache算法,本地缓存支持的默认空间为250M,使用线程池处理本地缓存,线程池的核心数量等于获得可用的处理器个数。

Load
load方法根据传入类型不同,有多个重载,每个重载方法最后都会返回一个DrawableTypeRequest 对象,他的父类DrawableRequestBuilder是一个支持链式调用的类。

加载图片的流程: 通过loadFromMemory从内存中读取,读取分为两级,先从loadFromActiveResources方法中读取,存储当前activity正在使用的资源。如果没有获取到,通过loadFromCache,从MemoryCache缓存中获取,该接口实现类为LruResourceCache。如果从loadFromMemory没有获取到缓存Resource,则从文件缓存或数据中读取。

Into
into是所有方法中最为复杂的,里边传入要显示图片的view,将处理后的图片设置到view上,因为涉及到UI的更新,所以底层会检查是否是主线程。
传入的view在glide底层被封装成了一个target对象,target能够获取自身绑定的请求,当发现之前的请求还在的时候,会把旧的请求清除掉,绑定新的请求,这也就是为什么控件复用时不会出现图片错位的问题。设置图片之前,首先会从memorycache中读取,如果没有从磁盘读取,当然读取resource还是result是有磁盘缓存的策略决定的,获取到对应的图片后将图片设置给imageview。

特殊形状图片设置: glide3设置图片形状通过transform方法里边传入自定义view,glide4新增了apply方法直接设置常用形状。

关于glide加载图片可能引发oom问题的处理: 自定义recyview,重写onViewRecycled方法,在方法内,将划出当前屏幕的item中,已经为空的imageview,调用glide的clear方法清除imageview中的资源。

4.Glide三级缓存

内存缓存:优先加载,速度最快

本地缓存:次优先加载,速度快

网络缓存:最后加载,速度慢,浪费流量

三级缓存策略,最实在的意义就是减少不必要的流量消耗,增加加载速度。

如今的 APP 网络交互似乎已经必不可少,通过网络获取图片再正常不过了。但是,每次启动应用都要从网络获取图片,或者是想重复浏览一些图片的时候,每次浏览都需要网络获取,消耗的流量就多了,在如今的流量资费来说,肯定会容易影响用户数量。

还有就是网络加载图片,有时候会加载很慢,影响了用户体验。

另外从开发角度来说,Bitmap 的创建非常消耗时间和内存,可能导致频繁GC。而使用缓存策略,会更加高效地加载 Bitmap,减少卡顿,从而减少读取时间。

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

5.三级缓存的原理

首次加载的时候通过网络加载,获取图片,然后保存到内存和 SD 卡中。

之后运行 APP 时,优先访问内存中的图片缓存。

如果内存没有,则加载本地 SD 卡中的图片。

具体的缓存策略可以是这样的:内存作为一级缓存,本地作为二级缓存,网络加载为最后。其中,内存使用 LruCache ,其内部通过 LinkedhashMap 来持有外界缓存对象的强引用;对于本地缓存,使用 DiskLruCache。加载图片的时候,首先使用 LRU 方式进行寻找,找不到指定内容,按照三级缓存的方式,进行本地搜索,还没有就网络加载。

LruCache 采用最近最少使用算法,设定一个缓存大小,当缓存达到这个大小之后,会将最老的数据移除,避免图片占用内存过大导致OOM。

Glide缓存机制大致分为三层:Lru算法缓存、弱引用缓存、磁盘缓存。

读取的顺序是:Lru算法缓存、弱引用缓存、磁盘缓存

写入的顺序是:弱引用缓存、Lru算法缓存、磁盘缓存(不准确)

6.Glide优点(与Fresco相比)

Glide:

多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)

生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)

高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)

高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)

Fresco:

最大的优势在于5.0以下(最低2.3)的bitmap加载。在5.0以下系统,Fresco将图片放到一个特别的内存区域(Ashmem区)

大大减少OOM(在更底层的Native层对OOM进行处理,图片将不再占用App的内存)

适用于需要高性能加载大量图片的场景

对于一般App来说,Glide完全够用,而对于图片需求比较大的App,为了防止加载大量图片导致OOM,Fresco 会更合适一些。并不是说用Glide会导致OOM,Glide默认用的内存缓存是LruCache,内存不会一直往上涨。

作者:无语_4c3f
链接:https://www.jianshu.com/p/9b4442d8e73b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值