DiskLruCache 并不能通过构造方法来创建,它提供了 open() 方法用于创建自身
File path = DiskFileUtils.getFilePath(context);
String pathString = path.getPath();
try {
diskLruCache = DiskLruCache.open(path,1,1,1000);
} catch (IOException e) {
e.printStackTrace();
}
open方法的四个参数说明
将图片的 url 转成 key 后,就可以获取 Editor 对象了。
对于这个 key 来说,如果当前不存在其他 Editor 对象,那么 edit() 就会返回一个新的 Editor 对象,通过它就可以得到一个文件输出流。需要注意的是,由于前面在 DiskLruCache 的 open 方法中设置了一个节点只能有一个数据,因此下面的 DISK_CACHE_INDEX 常量直接设为 0 即可,如下所示
String key = hashKeyFormUrl(url);
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor ! = null) {
OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);
}
当从网络下载图片时,图片就可以通过文件输出流写入到文件系统上,这个过程的实现如下所示
public boolean downloadUrlToStream(String urlString, utputStream outputStream) {
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection)url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE);
out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
int b;
while ((b = in.read()) ! = -1) {
out.write(b);
}
return true;
} catch (IOException e) {
Log.e(TAG, "Download bitmap failed. " + e);
} finally {
if (urlConnection ! = null) {
urlConnection.disconnect();
}
return false;
}
之后,还必须通过 Editor 的 commit() 来提交写入操作,真正地将图片写入文件系统。
如果图片下载过程发生了异常,那么还可以通过 Editor 的 abort() 来回退整个操作,这个过程如下所示
OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);
if (downloadUrlToStream(url, outputStream)) {
editor.commit();
} else {
editor.abort();
}
mDiskLruCache.flush();
经过上面的几个步骤,图片已经被正确地写入到文件系统了,接下来图片获取的操作就不需要请求网络了。
和缓存的添加过程类似
为了解决这个问题,可以通过文件流来得到它所对应的文件描述符,然后再通过 BitmapFactory.decodeFileDescriptor() 方法来加载一张缩放后的图片,这个过程的实现如下所示
Bitmap bitmap = null;
String key = hashKeyFormUrl(url);
DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
if (snapShot ! = null) {
FileInputStream fileInputStream = (FileInputStream)snapShot.getInputStream(DISK_CACHE_INDEX);
FileDescriptor fileDescriptor = fileInputStream.getFD();
bitmap = mImageResizer.decodeSampledBitmapFromFileDescriptor(fileDescriptor, reqWidth, reqHeight);
if (bitmap ! = null) {
addBitmapToMemoryCache(key, bitmap);
}
}
每个实体都是文件,你可以利用 fileInputStream 读取出里面的内容,然后做其他操作。
remove() 方法中要求传入一个 key,然后会删除这个 key 对应的缓存。示例代码如下
try {
String imageUrl = "https://chittyo/img.jpg";
String key = hashKeyForDisk(imageUrl);
mDiskLruCache.remove(key);
} catch (IOException e) {
e.printStackTrace();
}
remove() 方法我们并不经常去调用它。
我们完全不用担心因缓存数据过多而占用太多 SD 卡空间的问题,DiskLruCache 会根据我们在调用 open() 方法时设定的缓存最大值来自动删除多余的缓存。