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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值