深入探索Glide图片加载框架:做了哪些优化?如何管理生命周期?怎么做大图加载? |
您所在的位置:网站首页 › glide加载图片优化 › 深入探索Glide图片加载框架:做了哪些优化?如何管理生命周期?怎么做大图加载? |
前言
Glide可以说是最常用的图片加载框架了,Glide链式调用使用方便,性能上也可以满足大多数场景的使用,Glide源码与原理也是面试中的常客。 但是Glide的源码内容比较多,想要学习它的源码往往千头万绪,一时抓不住重点. 本文以Glide做了哪些优化为切入点,介绍与学习Glide的源码与原理,如果对您有所帮助,欢迎点赞. Glide做了哪些优化? 要想要回答这个问题,我们可以先想一想,如果我们自己要实现一个图片加载框架,我们会思考什么问题? 1.图片下载是个耗时过程,我们首先需要考虑的就是图片缓存的问题 2.图片加载也是个耗内存的操作,很多OOM都是图片加载导致的,所以我们也要考虑内存优化问题 3.图片加载到一半,页面关闭了,图片加载也应该中止,这又牵扯到了生命周期管理的问题 4.还有就是图片加载框架是否支持大图加载?大图情况下会有什么问题? 以上就是我们提出的有关于Glide的几个问题了,这样我们可以轻松得出本文主要包括的内容 1.Glide图片加载的总体流程介绍 2.Glide缓存机制做了哪些优化? 3.Glide做了哪些内存优化? 4.Glide如何管理生命周期? 5.Glide怎么做大图加载? 下面就带着问题进入正文~ 1.Glide图片加载总体流程介绍在开始了解Glide具体做了哪些优化之前,我们先对Glide图片加载的总体流程做一个简单的介绍,让大家首先有个整体概念。 同时在后面对Glide做的优化具体发生在哪一步也可以方便的知道. 概括来说,图片加载包含封装,解析,下载,解码,变换,缓存,显示等操作,如下图所示: 我们知道,下载图片是非常耗费资源的,所以图片缓存机制是图片加载框架很重要的一部分,下面就以一张表格来说明下 Glide 缓存。 缓存类型缓存代表说明活动缓存ActiveResources如果当前对应的图片资源是从内存缓存中获取的,那么会将这个图片存储到活动资源中。内存缓存LruResourceCache图片解析完成并最近被加载过,则放入内存中磁盘缓存-资源类型DiskLruCacheWrapper被解码后的图片写入磁盘文件中磁盘缓存-原始数据DiskLruCacheWrapper网络请求成功后将原始数据在磁盘中缓存在介绍具体缓存前,先来看一张加载缓存执行顺序,有个大概的印象 Glide的缓存机制,主要分为2种缓存,一种是内存缓存,一种是磁盘缓存。 之所以使用内存缓存的原因是:防止应用重复将图片读入到内存,造成内存资源浪费。 之所以使用磁盘缓存的原因是:防止应用重复的从网络或者其他地方下载和读取数据。 正式因为有着这两种缓存的结合,才构成了Glide极佳的缓存效果。 2.1 内存缓存Glide默认开启内存缓存,我们也可以通过skipMemoryCache关闭 上面我们可以看到内存缓存其实分两个部分,ActiveResource缓存与LRU缓存 ActiveResources 就是一个弱引用的 HashMap ,用来缓存正在使用中的图片,使用 ActiveResources 来缓存正在使用中的图片,可以保护这些图片不会被 LruCache 算法回收掉 内存缓存加载顺序如下: 1.根据图片地址,宽高,变换,签名等生成key 2.第一次加载没有获取到活动缓存。 3.接着加载内存资源缓存,先清理掉内存缓存,在添加进行活动缓存。 4.第二次加载活动缓存已经存在。 5.当前图片引用为 0 的时候,清理活动资源,并且添加进内存资源。 6.又回到了第一步,然后就这样环环相扣。 总结为流程图如下: 我们上面总结了Glide内存缓存加载的流程,看到这里我们很容易有个疑问,为什么Glide要设计两种内存缓存? 2.1.1 为什么设计两种内存缓存?LruCache算法的实现,你会发现它其实是用一个Set来缓存对象的,每次内存超出缓存设定触发trim操作的时候,其实是对这个Set进行遍历,然后移除缓存。但是我们都知道Set是无序的,因此遍历的时候有可能会把正在使用的缓存给误伤了,我还在用着它呢就给移出去了。因此这个弱引用可能是对正在使用中的图片的一种保护,使用的时候先从LruCache里面移出去,用完了再把它重新加到缓存里面。 举个例子 比如我们 Lru 内存缓存 size 设置装 99 张图片,在滑动 RecycleView 的时候,如果刚刚滑动到 100 张,那么就会回收掉我们已经加载出来的第一张,这个时候如果返回滑动到第一张,会重新判断是否有内存缓存,如果没有就会重新开一个 Request 请求,很明显这里如果清理掉了第一张图片并不是我们要的效果。所以在从内存缓存中拿到资源数据的时候就主动添加到活动资源中,并且清理掉内存缓存中的资源。这么做很显然好处是 保护不想被回收掉的图片不被 LruCache 算法回收掉,充分利用了资源。 2.1.1 小结本节主要总结了Glide内存缓存加载的流程 1.首先去获取活动缓存,如果加载到则直接返回,没有则进入下一步 2.接着去获取LRU缓存,在获取时会将其从LRU中删除并添加到活动缓存中 3.下次加载就可以直接加载活动缓存了 4.当图片引用为0时,会从活动缓存中清除并添加到LRU缓存中 5.之所以要设计两种内存缓存的原因是为了防止加载中的图片被LRU回收 2.2 磁盘缓存首先了解一下磁盘缓存策略 DiskCacheStrategy.NONE: 表示不缓存任何内容。DiskCacheStrategy.RESOURCE: 在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源。DiskCacheStrategy.DATA: 在资源解码前将原始数据写入磁盘缓存。DiskCacheStrategy.ALL : 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。DiskCacheStrategy.AUTOMATIC:它会尝试对本地和远程图片使用最佳的策略。当你加载远程数据时,AUTOMATIC 策略仅会存储未被你的加载过程修改过的原始数据,因为下载远程数据相比调整磁盘上已经存在的数据要昂贵得多。对于本地数据,AUTOMATIC 策略则会仅存储变换过的缩略图,因为即使你需要再次生成另一个尺寸或类型的图片,取回原始数据也很容易。默认使用这种缓存策略在了解磁盘缓存时我们主要需要明确一个概念,是当我们使用 Glide 去加载一张图片的时候,Glide 默认并不会将原始图片展示出来,而是会对图片进行压缩和转换,总之就是经过种种一系列操作之后得到的图片,就叫转换过后的图片。 我们既可以缓存变换之前的原始图片,也可以缓存变换后的图片 2.2.1 为什么需要两种磁盘缓存上文已经说了,DiskCacheStrategy.RESOURCE缓存的是变换后的资源,DiskCacheStrategy.DATA缓存的是变换前的资源 举个例子,同一张图片,我们先在100*100的View是展示,再在200*200的View上展示 如果不缓存变换后的类型相当于每次都要进行一次变换操作,如果不缓存原始数据则每次都要去重新下载数据 如下可以看出,两种缓存的key不一样 DiskCacheStrategy.RESOURCE currentKey = new ResourceCacheKey(helper.getArrayPool(),sourceId,helper.getSignature(),helper.getWidth(),helper.getHeight(),transformation,resourceClass,helper.getOptions()); DiskCacheStrategy.DATA DataCacheKey newOriginalKey = new DataCacheKey(loadData.sourceKey, helper.getSignature()); 3.Glide做了哪些内存优化?Glide的内存优化主要也是对Bitmap的优化,在回答这个问题前,我们可以想想有哪些常见的Bitmap优化手段 1.当图片大小与View大小不一致时,可以用inSampleSize进行尺寸优化 2.图片所占内存即宽高每像素所占内存大小,不同的模式每个像素所占的内存大小不同,我们可以利用inpreferredconfig配置 3.Bitmpa所占内存比较大,如果频繁创建回收Bitmap内存可能造成内存抖动,我们可以利用inBitmap利用Bitmap内存 4.内存缓存,上文我们已经介绍了Glide的弱引用缓存与LRU缓存 其实常见的Bitmap内存优化也就这么几种了,不过我们在工作中比较少直接使用他们。 下面我们就介绍下Glide中具体是怎么使用他们的. 3.1 尺寸优化当装载图片的容器例如ImageView只有100*100,而图片的分辨率为800 * 800,这个时候将图片直接放置在容器上,很容易OOM,同时也是对图片和内存资源的一种浪费。当容器的宽高都很小于图片的宽高,其实就需要对图片进行尺寸上的压缩,将图片的分辨率调整为ImageView宽高的大小,一方面不会对图片的质量有影响,同时也可以很大程度上减少内存的占用 我们通常使用inSampleSize对Bitmap进行尺寸缩放 如果inSampleSize 设置的值大于1,则请求解码器对原始的bitmap进行子采样图像,然后返回较小的图片来减少内存的占用,例如inSampleSize == 4,则采样后的图像宽高为原图像的1/4,而像素值为原图的1/16,也就是说采样后的图像所占内存也为原图所占内存的1/16;当inSampleSize |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |