您的位置:首页 > 其它

Bitmap高效加载、Cache和优化(二)

2016-09-11 14:51 274 查看
前面说到了内存缓存,接下来就要说说存储缓存。存储缓存采用DiskLruCache,将缓存对象写入文件系统实现缓存。

DiskLruCache源码不能直接使用,需要修改,使用方式有创建查找添加

1.DiskLruCache创建

DiskLruCache.open(File file,1,1,long maxsize);


用open创建,第一个参数是缓存路径,第二个是版本号,第三个是单节点对应的数据个数,一般这两个都设为1,第四个表示的是缓存总大小,超过这个值会清除一部分缓存。

<pre name="code" class="plain">File diskCacheDir = getDiskCacheDir(mContext, "bitmap");
if (!diskCacheDir.exists()) {
diskCacheDir.mkdirs();<span style="white-space:pre">	</span>//如果不存在目录便创建
}
mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1,DISK_CACHE_SIZE);


private static final DISK_CACHE_SIZE = 1024*1024*50;<span style="white-space:pre">	</span>//50M



2.添加缓存

DiskLruCache添加是通过Editor完成,Editor表示缓存对象的编辑对象

首先获取图片URL对应的key,在通过key获取Editor对象,DiskLruCache不许晕同时编辑一个缓存对象。

String key = hashKeyFormUrl(url);
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);
}
通过Editor得到一个文件输出流。

注意:前面设置DiskLruCache第三个参数时设为1,一个节点只能有一个数据,所以DISK_CACHE_INDEX直接设为0。

图片通过这个文件输出流写到文件系统上

public boolean downloadUrlToStream(String urlString,
OutputStream 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, "downloadBitmap failed." + e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
MyUtils.close(out);
MyUtils.close(in);
}
return false;
}


除此之外还必须通过editor的commit()来提交写入操作,如果异常,通过Editor的abort()回退整个操作

所以上述的代码改成

String key = hashKeyFormUrl(url);
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);
if (downloadUrlToStream(url, outputStream)) {
editor.commit();
} else {
editor.abort();
}
mDiskLruCache.flush();
}


执行提交或回退

3.缓存查找

缓存查找也是把URL转化为key,通过DiskLruCache的get方法得到一个Snapshot对象,再通过Snapshot对象得到缓存文件的输入流,得到Bitmap对象。

注意:为避免OOM,一般不建议直接加载原始图片所以要加载缩略图。

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);
}
}

decodeFileDescriptor比decodeFile相比要消耗更小的内存

以上代码来自于《Android开发艺术探究》这本书
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DiskLruCache 缓存