android文件缓存策略,Android:跟着实战项目学缓存策略之DiskLruCache详谈

Android:跟着实战项目学缓存策略之DiskLruCache详谈

写在前面

之前花费大心思更新了一篇《Android:跟着实现项目学缓存策略之LruCache详谈》,本来是准备用项目实战的方式分享一下缓存策略的使用。但是由于篇幅过长,DiskLruCache也比较复杂,所以决定把DiskLruCache抽取出来单独讲。

本文仍然是在上一篇文章中新闻小项目基础上来说明DiskLurCache的用法,以及与LruCache的不同。文章的目录如下:

写在前面

遗留问题

DiskLruCache详解

基本介绍

实战运用

缓存策略对比与总结

结语

项目源码

遗留问题

上一篇文章中已经将图片成功的缓存到内存中,当所有图片缓存完成后,再次滑动就已经不需要重新加载图片了。但是注意看下面这张图的现象:

94b713a68fc8173cd286dbdc05051940.gif

可以看到,成功缓存后确实在应用内再次滑动就不需要加载了,但是如果此时我们kill掉APP,重新打开的话,仍然是需要加载的。这是为什么呢?

答案很显然,因为LruCache是将文件类型缓存到内存中,随着APP中Activity的销毁,内存也会随之回收。也就将内存中的缓存回收掉,再次打开APP的时候,内存中找不到缓存,当然需要重新加载了。

所以如何才能缓存到存储设备中呢?下面就来详细说说。

DiskLruCache详解

基本介绍

DiskLruCache与LruCache不同,它不是Android中已经封装好的类,所以 想要使用的话需要从网上下载。关于下载这个类,我也是费了不少功夫,大家如果想尝试的话,可以直接Copy我这个项目中的

DiskLruCache用于实现存储设备缓存,即磁盘缓存,它通过将缓存对象写入文件系统从而实现缓存的效果。

注意,重点是将缓存对象写入文件系统,大家可能不太理解,不过不用担心,后面会说到。先来它的创建、添加、获取方法。

1、创建

与LruCache不同的是,它不能通过构造方法的方式来创建,它的创建方法是通过DiskLruCache类的一个静态方法 open 来创建。具体如下:

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

其中有四个参数,很好理解:

File directory:这是缓存文件在磁盘中的存储路径,这是必须要指定的,一般来说是选择SD卡上的缓存目录,APP卸载后自动删除缓存。

int appVersion:这个是版本号,用处不大,正常设置为1即可。

int valueCount:这个是单个节点所对应的数据个数,其实就是一个key对应多少个value,正常设置为1即可,这样key和value一一对应,方便查找。

long maxSize:这个就是缓存的总大小,很好理解。

这样看来,创建一个DiskLruCache就至少要指定文件的目录与缓存大小。所以创建方式如下:

//DiskLruCache

private DiskLruCache mDiskCache;

//指定磁盘缓存大小

private static final long DISK_CACHE_SIZE = 1024 * 1024 * 50;//50MB

//得到缓存文件

File diskCacheDir = getDiskCacheDir(mContext, "diskcache");

//如果文件不存在 直接创建

if (!diskCacheDir.exists()) {

diskCacheDir.mkdirs();

}

mDiskCache = DiskLruCache.open(diskCacheDir, 1, 1,DISK_CACHE_SIZE);

/**

* 创建缓存文件

*

* @param context 上下文对象

* @param filePath 文件路径

* @return 返回一个文件

*/

public File getDiskCacheDir(Context context, String filePath) {

booleanexternalStorageAvailable= Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

final String cachePath; if (externalStorageAvailable){

cachePath= context.getExternalCacheDir().getPath();

} else {

cachePath= context.getCacheDir().getPath();

}

return new File(cachePath+ File.separator + filePath);

}

注意,下面的方法是一个工具方法,用来返回一个文件,难度不大。这样就创建了一个DiskLruCache。

2、设置key

一般来说,需要用到缓存的地方都是需要联网下载的,所以这个key最好的就是需要下载的文件的Url。但是Url中可能有一些特殊字符,所以最好的方式就是将其转换成MD5值。

MD5是计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。

说简单点,就是一种加密算法,将一串信息转成定长的一串字符。这里只是防止Url中的特殊字符影响正常使用。下面给出如何转成MD5,这是《Android开发艺术探索》中的源码,可以当成工具方法,直接用即可。

/**

* 将URL转换成key

*

* @param url 图片的URL

* @return

*/

private String hashKeyFormUrl(String url) {

String cacheKey;

try {

final MessageDigest mDigest = MessageDigest.getInstance("MD5");

mDigest.update(url.getBytes());

cacheKey = bytesToHexString(mDigest.digest());

} catch (NoSuchAlgorithmException e) {

cacheKey = String.valueOf(url.hashCode());

}

return cacheKey;

}

/**

* 将Url的字节数组转换成哈希字符串

*

* @param bytes URL的字节数组

* @return

*/

private String bytesToHexString(byte[] bytes) {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < bytes.length; i++) {

String hex = Integer.toHexString(0xFF & bytes[i]);

if (hex.length() == 1) {

sb.append('0');

}

sb.append(hex);

}

return sb.toString();

}

3、添加

与LruCache不同的是,LruCache内部实现是Map,添加直接用put即可;而DiskLruCache是将文件存储到文件中,所以需要通过文件输出流的形式将文件写入到文件系统中。但是仅仅写入是不够的,必须通过Editor对象来提交。它是缓存对象的编辑对象。它是根据文件的Url对应的key的 edit() 方法获取。

值得注意的是,如果返回的Editor对象正在被编辑,那么返回的结果不为null。反之如果返回null,表示编辑对象可用。所以我们在使用前必须判断一下返回的Editor对象是否为空。如果不为空的话,那就通过Editor对象的 commi 方法来提交写入操作,当然你也可以通过 abort 方法来撤销写入操作。

说了这么多,归纳来说DiskLruCache的添加操作分为三步:

通过文件的Url将文件写入文件系统

通过Url对应的key来得到一个不为空的Editor对象

通过这个Editor对象来对写入操作进行提交或者撤销操作

好了,现在来看具体的实现代码,代码逻辑应该很清晰:

/**

* 将URL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值