Android之三级缓存

啥是三级缓存

三级缓存指的是:

  • 网络缓存(顺序优先级最低)
  • 本地缓存 (优先级次之)
  • 内存缓存(优先级最高)

为啥使用三级缓存

我们的App 经常会需要进行网络交互,通过网络获取图片是非常正常的事情。如果每次启动的时候都从网络拉取图片的话,这会消耗很多流量。对于用户来讲,流量就意味着电话费,一个很耗流量的应用肯定会多花套餐钱,这样用户数量肯定要受到影响。
特别是当我们需要重复浏览加载一些图片时,如果每一次浏览都通过网络来获取加载,流量的浪费可想而知有多大。所以才提出三级缓存策略,通过网络、本地、内存三级缓存图片,来减少不必要的网络交互,避免浪费流量。

三级缓存基本原理

首次加载 App 时,通过网络来获取图片,然后我们将图片保存至本地SD卡和内存中
之后运行 App 时,优先访问内存中的图片缓存,若内存中没有,再加载本地SD卡中的图片,若本地SD卡中也没有就从网络中加载。

如何使用三级缓存

内存缓存
Lru(Least rencently used) :近期最少使用算法。LruCache和DisLruCache两个类,分别用于内存和硬盘缓存。核心思想是当缓存空间满了之后,会删除最近最少使用的缓存。
LruCache类使用
LruCache的原理是将缓存对象作为强引用,保存在LinkedHashMap中,当缓存满了之后,将对象从Map中移除,重新通过put方法添加新的缓存,get方法获取缓存。

int maxMemory = (int) (Runtime.getRuntime().totalMemory()/1024);

int cacheSize = maxMemory/8;

mMemoryCache = new LruCache(cacheSize){

@Override

protected int sizeOf(String key, Bitmap value) {

       return value.getRowBytes()*value.getHeight()/1024;

} };

LruCache的核心思想就是维护一个缓存对象的队列,该队列由LinkedHashMap维护。一直没访问的对象放在队尾,最新访问的放在队首,当队列满了之后,从队尾开始淘汰,队首的最后淘汰。
本地缓存
由于DiskLruCache并不是由Google官方编写的,所以这个类并没有被包含在Android API当中,我们需要将这个类从网上下载下来,然后手动添加到项目当中。DiskLruCache的源码在Google Source上,地址如下:
android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java
下载好了源码之后,只需要在项目中新建一个io包,然后将DiskLruCache.java文件复制到这个包中即可。
DiskLruCache是不能new出实例的,如果我们要创建一个DiskLruCache的实例,则需要调用它的open()方法,接口如下所示:

public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)

open()方法接收四个参数,第一个参数指定的是数据的缓存地址,缓存地址通常都会存放在 /storage/Android/data/<你的包名>/cache, 这个路径下第二个参数指定当前应用程序的版本号,第三个参数指定同一个key可以对应多少个缓存文件,基本都是传1,第四个参数指定最多可以缓存多少字节的数据。
得到DiskLruCache的实例之后就可以对缓存的数据进行操作了,主要是写入、访问、移除等操作。
写入的操作是借助DiskLruCache.Editor这个类完成的。类似地,这个类也是不能new的,需要调用DiskLruCache的edit()方法来获取实例,接口如下所示:

public Editor edit(String key) throws IOException

可以看到,edit()方法接收一个参数key,这个key将会成为缓存文件的文件名,并且必须要和图片的URL是对应的。

String imageUrl = "https://xxx/xx/xx.jpg";
String key = hashKeyForDisk(imageUrl);
DiskLruCache.Editor editor = mDiskLruCache.edit(key);

有了DiskLruCache.Editor的实例之后,我们可以调用它的newOutputStream()方法来创建一个输出流,然后把它传入到downloadUrlToStream()中就能实现下载并写入缓存的功能了。注意newOutputStream()方法接收一个index参数,由于valueCount是1,所以index传0就可以了。在写入操作执行完之后,还需要执行commit()方法进行提交才能使写入生效,而调用abort()方法的话则表示放弃此次写入。

if (editor != null) {
				OutputStream outputStream = editor.newOutputStream(0);
				if (cacheToLocal(imageStream, outputStream)) {
					editor.commit();
				} else {
					editor.abort();
				}
			}
			mDiskLruCache.flush();

网络缓存
通过异步网络请求,获取网络资源

参考文章链接:https://blog.csdn.net/guolin_blog/article/details/28863651

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值