Android图片的三级缓存管理
2015-09-10 14:54
411 查看
Android的很多应用程序都有多图片的浏览功能,而图片多了很容易造成OOM,而且处理不好用户体验会很差,本文应用了一个硬缓存-软缓存-硬盘缓存的图片加载机制,来加快图片加载的速度和避免出现OOM。
一、设计分析:
1、硬缓存,在内存中级别最高,不会被GC回收的部分,使用LruCache;软存使用SoftReference,在内存中级别低于硬缓存,在内存紧张的时候会被GC回收;硬盘缓存使用DiskLruCache。对于lrucache与DiskLruCache不熟悉的,可参考http://blog.csdn.net/guolin_blog/article/details/34093441
2、实现原理,最近使用的图片存入LruCache中,在LruChche中被清除的图片放入软存,而全部图片都在硬盘中缓存一份。当需要加载图片时,先搜索LruCache,有直接返回,没有继续搜索SoftReference,如果有,先将图片取出在SoftReference中删除,存入LruCache并返回,没有继续搜索DiskLruCache,如果没有就开启任务去网络下载。下载完成后在LruCache中缓存一份,在DiskLruCache中缓存一份。
二、代码分析:
1、LruCache的初始化与设置
LruCache的可缓存大小设置为本机为本应用开辟的最大内存的1/8,实现entryRemoved方法,在这里面将要被移除的图片加入软存中。
2、软存设置
软存使用LinkedHashMap配合SoftReference的形式
这里设置软存的最大存储量是15个,重写removeEldestEntry方法,当图片数量多于15个时,销毁最早进入的图片。
3、硬盘缓存直接使用比较成熟稳定的DiskLruCache
DiskLruCache不熟悉的可以参考
http://blog.csdn.net/guolin_blog/article/details/28863651
4、如果以上三步没有拿到bitmap,那么就要去网络下载了,本文使用AsyncTask下载。并使用set和List模仿一个简单的线程池,控制图片下载的并发数。具体代码参见:
http://download.csdn.net/detail/suyiyang888/9095027
水平有限,仅供参考。
感谢:
http://my.csdn.net/sinyu890807
一、设计分析:
1、硬缓存,在内存中级别最高,不会被GC回收的部分,使用LruCache;软存使用SoftReference,在内存中级别低于硬缓存,在内存紧张的时候会被GC回收;硬盘缓存使用DiskLruCache。对于lrucache与DiskLruCache不熟悉的,可参考http://blog.csdn.net/guolin_blog/article/details/34093441
2、实现原理,最近使用的图片存入LruCache中,在LruChche中被清除的图片放入软存,而全部图片都在硬盘中缓存一份。当需要加载图片时,先搜索LruCache,有直接返回,没有继续搜索SoftReference,如果有,先将图片取出在SoftReference中删除,存入LruCache并返回,没有继续搜索DiskLruCache,如果没有就开启任务去网络下载。下载完成后在LruCache中缓存一份,在DiskLruCache中缓存一份。
二、代码分析:
1、LruCache的初始化与设置
int maxMemory = (int) Runtime.getRuntime().maxMemory(); int cacheSize = maxMemory / 8; // 硬引用缓存容量,为系统分配内存的1/8 mLruCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { if (value != null) return value.getRowBytes() * value.getHeight(); else return 0; } @Override protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) { if (oldValue != null) // 硬引用缓存容量满的时候,会根据LRU算法把最近没有被使用的图片转入此软引用缓存 mSoftCache.put(key, new SoftReference<Bitmap>(oldValue)); } };
LruCache的可缓存大小设置为本机为本应用开辟的最大内存的1/8,实现entryRemoved方法,在这里面将要被移除的图片加入软存中。
2、软存设置
软存使用LinkedHashMap配合SoftReference的形式
private LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache; private final int SOFT_CACHE_SIZE = 15; mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>( SOFT_CACHE_SIZE, 0.75f, true) { private static final long serialVersionUID = 1L; @Override protected boolean removeEldestEntry( Entry<String, SoftReference<Bitmap>> eldest) { if (size() > SOFT_CACHE_SIZE) { return true; } return false; } };
这里设置软存的最大存储量是15个,重写removeEldestEntry方法,当图片数量多于15个时,销毁最早进入的图片。
3、硬盘缓存直接使用比较成熟稳定的DiskLruCache
/** * 硬盘缓存版本 */ private final int DISKLRU_VERSON = 1; /** * 硬盘缓存大小 */ private final int DISKLRU_SIZE = 10 * 1024 * 1024; /** * 硬盘缓存文件名称 */ private final String DISKLRU_NAME = "imagecache"; private DiskLruCache mDiskLruCache; try { // 获取图片缓存路径 File cacheDir = getDiskCacheDir(context, DISKLRU_NAME); if (!cacheDir.exists()) { cacheDir.mkdirs(); } // 创建DiskLruCache实例,初始化缓存数据 mDiskLruCache = DiskLruCache.open(cacheDir, Utils.getAppVersion(context), DISKLRU_VERSON, DISKLRU_SIZE); } catch (IOException e) { e.printStackTrace(); }
DiskLruCache不熟悉的可以参考
http://blog.csdn.net/guolin_blog/article/details/28863651
4、如果以上三步没有拿到bitmap,那么就要去网络下载了,本文使用AsyncTask下载。并使用set和List模仿一个简单的线程池,控制图片下载的并发数。具体代码参见:
http://download.csdn.net/detail/suyiyang888/9095027
水平有限,仅供参考。
感谢:
http://my.csdn.net/sinyu890807
相关文章推荐
- Lua的内存管理浅析
- Enterprise Library for .NET Framework 2.0缓存使用实例
- PowerShell中编程清空IE缓存方法
- PowerShell中使用.NET将程序集加入全局程序集缓存
- C#中缓存的基本用法总结
- wap开发中如何有效的利用缓存减少消息的传送量
- PHP基于文件存储实现缓存的方法
- smarty缓存用法分析
- 引用全局程序集缓存内的程序集的方法
- asp Response.flush 实时显示进度
- C#实现清除IE浏览器缓存的方法
- ASP.NET缓存管理的几种方法
- 清除aspx页面缓存的程序实现方法
- C#缓存之SqlCacheDependency用法实例总结
- jQuery数据缓存用法分析
- Jquery validation remote 验证的缓存问题解决方法
- IE9下Ajax无法刷新数据的缓存问题解决方法
- Ajax获取页面被缓存的解决方法
- ASP.NET网站管理系统退出 清除浏览器缓存,Session的代码
- IE cache缓存 所带来的问题收藏