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

来源:互联网 发布:recyclerview清空数据 编辑:程序博客网 时间:2024/05/16 14:52

前面说到了内存缓存,接下来就要说说存储缓存。存储缓存采用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开发艺术探究》这本书


0 0
原创粉丝点击