导读 Glide-缓存基础(caching-basics) 前几篇传送门: glidecache什么文件夹 glide文件夹可以删除吗 原文传送门: 正文: 在了解

Glide-缓存基础(caching-basics)

前几篇传送门:

glidecache什么文件夹 glide文件夹可以删除吗glidecache什么文件夹 glide文件夹可以删除吗


原文传送门:

正文:

在了解完图片的加载、显示、处理之后,接下来继续研究优化。成功、高效加载图片的基本特性之一就是利用缓存。在本文,我们将会了解Glide的缓存机制的基础部分。

在设计一款Android应用的时候,一个好用的图片加载框架应该尝试最小化网路请求的次数。Glide也一样,Glide默认通过内存和磁盘缓存来避免不必要的网络请求。在后续的文章中我们会具体看看其实现细节。如果你已经迫不及待,随时可以查看这个 官方文档 :

对于现在,重要的是,所有的图片请求都会在内存和磁盘上建立缓存。缓存通常都是非常有用的,然而在某些情况下又不希望它这么做。在下一节,我们将学习如何在一次请求中改变Glide的缓存策略。

如果你使用过Glide,你注意到根本不需要为开启缓存做额外的事,它自然而然就实现了。然而,如果你知道某张图片改变非常快,那么你应该要避免某些缓存。

Glide提供了一些方法来调整内存和磁盘缓存策略,让我们先来看看内存缓存。

我们假设一种非常简单的情形:从网络上加载一张图片到ImageView上:

你已经注意到我们这里使用 .skipMemoryCache( true ) 来特地告诉Glide,让它跳过内存缓存。这意味着Glide不会将它放入到内存缓存当中。需要注意的是,这只是影响了内存缓存,Glide依然会使用磁盘缓存来避免额外的网络请求。

很容易理解的是,Glide是默认将所有的图片资源都加入到内存缓存中的。因此,没有必要专门去调用 .skipMemoryCache( false ) 这个方法。

提示:要注意的是,对于同一个图片链接,如果你初次请求的时候没有调用 .skipMemoryCache( true ) ,后面又调用了这个方法,那么它会被加入到内存缓存当中。当你想调整缓存策略的时候,确保你在请求同一个图片的时候保持策略统一。

基于你已经学习完上面的章节,你知道即使让 内存缓存 失效,图片请求依然会将图片存储在设备的磁盘上。如果你有一张图片,它指向同一个链接上,但是它改变得很快,那么你可能也不想让它存储在磁盘上。

你可以通过 .diskCacheStrategy() 方法改变Glide的 磁盘缓存策略 。与 .skipMemoryCache() 不同的是,它需要传入不同的枚举值,而不仅仅是布尔值。如果你想让磁盘缓存 失效 ,将 DiskCacheStrategy.NONE 作为参入传入即可:

这样的话,这张图片的一点磁盘缓存都不会有。然而,它默认会使用 内存缓存 。为了让两个缓存都失效,把它俩组合一下就好:

我们前面已经提到了,对于磁盘缓存,Glide不止一个选项。在知道有哪些选项之前,你要明白磁盘缓存是相当复杂的东西。例如,Picasso只是缓存完整图片。然而,Glide的缓存不仅缓存原图、完整的图片还有额外一些缩小的图片。

例如,如果你请求一张图片是1000 x 1000像素,然后你的ImageView是500 x 500像素,那么Glide会将这两个尺寸图片都缓存起来。

现在你应该明白磁盘缓存策略 diskCacheStrategy() 中,不同的枚举参数之间的区别了:

作为最后一个例子,如果你有一张图片,你知道会经常修改它并且会有各种不同的版本,那么把它指定为仅缓存原图是很有意义的。因此,我们可以使用 DiskCacheStrategy.SOURCE 来告诉Glide仅缓存原图即可:

由于Glide对于同一张图片可以采取不一样的的缓存方式,想要简单的清除某张图片的缓存不是一件容易的事。你需要找到这张图片所有的变体,然后针对性地让那个缓存失效。

这是一个相当繁琐的步骤, 官方文档 里讲解得非常清楚。

在本文,你学习了Glide缓存图片的基础知识,并且知道如何调整缓存策略。基于你的需求,在后续的博文里,我们将回到这个话题讲解更多高级的优化。然而,这篇文章已经提供了非常有效的方法让你可以好好地利用Glide的缓存了。

下周,我们将看看 良好的用户体验的另一个关键点:优先图片请求!

glidecache用什么软件可以查看?

很多的,像EVEREST、GPU-Z、鲁大师

等都可以查看显卡的具体参数,这里介绍GPU-Z查看显卡具体参数的步骤:搜索GPU-Z并下载安装。运行已安装的软件,在主界面就可以看到显卡的具体参数了。

英文看不明白也可以直接搜索GPU-Z中文版下载安装。

手机glidecache是什么文件夹,能删掉吗?

glidecache是图片缓存的文件夹,该文件夹可以删除,但是删除的同时会删除手机中的缓存图片,通过删除此文件夹删除的缓存图片无法找回,一旦删除无法恢复。

手机缓存是数据交换的缓冲区,缓存是CPU的一部分,它存在于CPU中,而CPU存取数据的速度则非常的快,一秒钟能够存取,处理十亿条指令和数据。

而内存就慢很多,缓存是为了解决CPU速度和内存速度的速度差异问题,在打开文件时,系统会将数据从内存中复制到一个缓冲区而再打开文件时,系统会直接读取缓存中的数据,则不用到内存中读取, 这样浏览文件的速度会比较快。

Glide ② — 缓存机制

阅读本文需要先了解 Glide加载流程

首先介绍一下Glide中对图片资源的封装类: EngineResource

在活动缓存中,使用了一个map用来存放EngineResource对象,这里需要注意一个操作,就是这个EngineResource对象是用WeakReference包裹的,并且通过ReferenceQueue监听了EngineResource的回收,在回收的时候会清理当前的活动缓存内容;

下面分析一下源码是如果实现的:

首先,自定义一个WeakReference类,将key和resource传进入(用于在WeakReference回收的时候释放),传入一个ReferenceQueue对象,用于监听WeakReference回收

开启一个子线程,在循环中监听ReferenceQueue的返回值,通过这个返回值,判断WeakReference有没有回收,监听的方法是ReferenceQueue.remove(),这是一个阻塞方法;所以要开子线程;

LruResourceCache继承了LruCache类,关于LruCache类,简单提一下,具体的可以参考我之前的博客 LruCache实现 ,LruCache继承了LinkedHashMap,LinkedHashMap有一个特点,就get后的数据会移动到队列,这就是Lru思想:固定一个容量,put的时候如果超过容量了,将最后一个节点删除,get的时候将get的这个节点移动到队列的头部;

onItemEvicted()方法是LruCache的一个空方法,调用的时机是在put的时候判断是否超过容量,如果超过容量了,就淘汰最后一个节点,并调用这个方法;

活动缓存和内存缓存都是缓存在内存中的,活动缓存缓存的是正在使用的图片资源,当图片不使用时会放到内存缓存中,提出活动缓存的目的:单一的内存缓存由于Lru的淘汰机制会导致图片加载不稳定

首先介绍一个磁盘缓存方案DiskLruCache(非Google官方编写,但获得官方认证),关于这个磁盘缓存方案的理解可以看郭林的这片文章:

Android DiskLruCache完全解析,硬盘缓存的最佳方案

从上一篇文章知道,Glide加载操作是通过 Engine 来驱动的

Engine的load()中,首先尝试从 活动缓存 和 内存缓存 获取缓存,如果没有缓存再启动EngineJob和DecodeJob; 上面介绍了缓存的获取,下面看一下缓存的存放,肯定是在获取到图片后的回调中存放的

在DecodeJob获取到图片数据后,会回调很多接口,在回调中会将其放入 活动缓存 ,当图片不在使用的时候,就会放入内存缓存,根据上面介绍的活动缓存规则,当 EngineResource 计数为0时就应该放入内存缓存;

当资源引用为0,回调onResourceReleased(),从活动缓存移除,放入内存缓存;

上面介绍了活动缓存和内存缓存的存放和获取,下面看一看磁盘缓存的存取;

还记得 DataFetcherGenerator 接口吗?这个接口是DecodeJob用于获取数据的,有三个具体的实现:

我们在上一篇具体介绍的是网络文件的获取,这里的磁盘缓存使用的就是 DataCacheGenerator(缓存文件) 这个Generator了

上篇文章知道DecodeJob是一个Runnable任务,在run()会调用runWrapped(),在runWrapped()中会做三种事情:

在runWrapped()的解码操作中会执行decode(),在decode()中,会disk put操作;

Glide的磁盘缓存是基于DiskLruCache 实现的,Glide直接使用的是DiskLruCacheWrapper对象对DiskLruCache 的封装;

Glide基础用法加缓存

这篇文章给大家介绍下android目前使用比较广泛的一个图片缓存库—Glide,这个库是google的一位开发人员在github上的一个开源项目。目前google的一些官方应用都在使用它,所以你现在就开始放心的用吧。

github地址

Glide基础用法加缓存

添加Glide

在module的build.gradle中添加以下依赖:

compile 'com.github.bumptech.glide:glide:3.7.0'

/** 250 MB of cache. */

int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;

Glide.get(this).clearMemory();

Glide.get(MainActivity.this).clearDiskCache();

public class WangGlideModule implements GlideModule {

}

...

public class WangGlideModule implements GlideModule {

}public class WangGlideModule implements GlideModule {

}public class WangGlideModule implements GlideModule {

}public class WangGlideModule implements GlideModule {

}public class WangGlideModule implements GlideModule {

}public class WangGlideModule implements GlideModule {

}public class WangGlideModule implements GlideModule {

运行后手机文件夹里面多出来一个GlideDisk文件夹,这个就是磁盘缓存的目录