Bitmap高效加载、Cache和优化(二)
2016-09-11 14:51
274 查看
前面说到了内存缓存,接下来就要说说存储缓存。存储缓存采用DiskLruCache,将缓存对象写入文件系统实现缓存。
DiskLruCache源码不能直接使用,需要修改,使用方式有创建查找添加
1.DiskLruCache创建
用open创建,第一个参数是缓存路径,第二个是版本号,第三个是单节点对应的数据个数,一般这两个都设为1,第四个表示的是缓存总大小,超过这个值会清除一部分缓存。
2.添加缓存
DiskLruCache添加是通过Editor完成,Editor表示缓存对象的编辑对象
首先获取图片URL对应的key,在通过key获取Editor对象,DiskLruCache不许晕同时编辑一个缓存对象。
注意:前面设置DiskLruCache第三个参数时设为1,一个节点只能有一个数据,所以DISK_CACHE_INDEX直接设为0。
图片通过这个文件输出流写到文件系统上
除此之外还必须通过editor的commit()来提交写入操作,如果异常,通过Editor的abort()回退整个操作
所以上述的代码改成
执行提交或回退
3.缓存查找
缓存查找也是把URL转化为key,通过DiskLruCache的get方法得到一个Snapshot对象,再通过Snapshot对象得到缓存文件的输入流,得到Bitmap对象。
注意:为避免OOM,一般不建议直接加载原始图片所以要加载缩略图。
decodeFileDescriptor比decodeFile相比要消耗更小的内存
以上代码来自于《Android开发艺术探究》这本书
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开发艺术探究》这本书
相关文章推荐
- Bitmap高效加载、Cache和优化(一)
- Android Bitmap的加载优化与Cache相关介绍
- Bitmap的高效加载和 Cache
- Bitmap高效加载和Cache(一)
- 基于android示例程序(bitmapfun) 高效加载图片让人无语地方
- 【Android Training - Graphics】高效地显示Bitmap图片(Lesson 4 - 优化Bitmap的内存使用)
- 高效的加载大Bitmap(位图)
- 高效地显示Bitmap图片 1 - 有效率地加载大尺寸的位图
- 【Google官方教程】第一课:高效的加载大Bitmap(位图)
- 高效地加载大Bitmap(位图)
- Anroid高效显示Bitmap图片,减少OOM问题,加载大尺寸位图
- 【Google官方教程】第一课:高效的加载大Bitmap(位图)
- 高效使用Bitmaps(二) 后台加载Bitmap
- 关于android示例程序(bitmapfun)——高效加载图片的坑爹地方
- 【Google官方教程】第一课:高效地加载大Bitmap(位图)
- 【Google官方教程】第一课:高效地加载大Bitmap(位图)
- 第一课:高效地加载大Bitmap(位图)
- 译:Google官方教程】高效的加载大Bitmap(位图)
- 【Google官方教程】第一课:高效地加载大Bitmap(位图)
- 【Google官方教程】第一课:高效地加载大Bitmap(位图)