android Lru图片缓存管理方案
原文地址
http://blog.csdn.net/ceko_wu/article/details/45244259
1、图片缓存管理的必要性
Android应用为什么要做一些图片缓存的管理?
1)内存管理必要性
android每个进程的虚拟机对内存的管理与其他的一些系统不太一样,比如iOS,ios对于内存这块的管理,开发者可以自己手动去释放,但在android中没有提供给开发人员释放内存的功能,android虚拟机只有在内存达到限制 的值时才会主动去回收,应用调用System.gc也不能解决内存问题,gc()函数的作用只是提醒虚拟机:程序员希望进行一次垃圾回收。但是它不能保证垃圾回收一定会进行,而且具体什么时候进行是取决于具体的虚拟机 的,不同的虚拟机有不同的对策。
应用中我们有大量的图片操作,比如像论坛类型的应用,我们加载过的图片肯定希望下次加载的时候能够更快的使用,如果可以放在内存中,无疑将会是最快的,但内存是有限的,每个进程最大的内存是有限制的,且又因为它的回收机制,所以我们必须要做内存管理,否则会出现oom。
2)磁盘管理的重要性
内存是有限的,不可能所有的图片都放在内存中,但需要提升加载速度,节约流量,下载过的图片希望下次继续使用,只能存放在本地磁盘中,android中的磁盘与pc机不太一样,三方应用可以使用的磁盘一个是应用安装目录/data/data/包名,另外就是sdcard目录,但虽然是本地缓存我们也不能缓存过多的文件,如果缓存过多会占用太多的空间。
2、LRU 内存管理实现方案
java.util.LinkedHashMap
java提供了LinkedHashMap,它是HashMap的一种,它有一个重要的功能可以设置存放的元素最大的个数,当map中的元素超过设置的值时,它可以移除最老的值。
它实现了lru的算法。实现原理
根据LinkedHashMap的功能,我们将图片的bitmap存到LinkedHashMap中,且设置存储最大的值,根据其原理,如果超过其容量就会自动移除最老的值。
public class LRULinkedHashMap |
下载好的图片直接通过put(url,bitmap)存储起来,需要的使用的时候通过get(url)判断是否有存储在内存中,如果存储则直接使用bitmap,当然bitmap最好使用弱引用
3、磁盘LRU 管理实现方案
磁盘管理采用google开源jar包 disklrucache-2.0.1.jar,该jar实现了对本地文件的管理。
1)初始化
public DiskLruImageCache(Context context,String uniqueName, int diskCacheSize, CompressFormat compressFormat, int quality ) { try { final File diskCacheDir = getCacheDir(context, uniqueName ); mDiskCache = DiskLruCache.open( diskCacheDir, APP_VERSION, VALUE_COUNT, diskCacheSize ); mCompressFormat = compressFormat; mCompressQuality = quality; } catch (IOException e) { e.printStackTrace(); } } |
需要设置保存的路径以及压缩方式,以及最大存储大小。
2)存储
public void putBitmap( String key, Bitmap data ) { UtilLog.d("putBitmap key==="+key); DiskLruCache.Editor editor = null; try { editor = mDiskCache.edit( key ); if ( editor == null ) { return; } OutputStream out = null; boolean result=false; try { out = editor.newOutputStream( 0 ); result= data.compress( mCompressFormat, mCompressQuality, out ); editor.commit(); mDiskCache.flush(); } finally { if ( out != null ) { out.close(); } } } catch (IOException e) { e.printStackTrace(); try { if ( editor != null ) { editor.abort(); } } catch (IOException ignored) { ignored.printStackTrace(); } } } |
根据图片的url作为查询的key值进行存储
3)获取存储的图片
public Bitmap getBitmap( String key ) { Bitmap bitmap = null; DiskLruCache.Snapshot snapshot = null; try { snapshot = mDiskCache.get( key );if (snapshot != null) {InputStream inputStream = snapshot.getInputStream(0);if (inputStream != null) {bitmap = BitmapFactory.decodeStream(inputStream);inputStream.close();}} } catch ( IOException e ) { e.printStackTrace(); } finally { if ( snapshot != null ) { snapshot.close(); } } return bitmap; } |
获取时根据图片的url获取图片的bitmap
4、图片缓存管理方案总结
在实际应用中,由于内存的读取速度比磁盘的读取速度快很多,所以优先使用内存,如果内存中没有的情况下再从磁盘查找,如果磁盘查找没有的情况下再从网络下载。
当然现在图片的缓存这块也可以不用自己手动处理,有很多的三方jar包已经实现了这些功能,使用也比较方便。Android-Universal-Image-Loader实现上述的管理。
更多相关文章
- 【Android】安卓常见的内存泄漏:OOM,bitmap
- Android 匿名共享内存C接口分析
- Android避免context相关内存溢出
- Android 中动态提取图片中颜色作为主题色
- ListView有背景图片或背景颜色,那么在滑动ListView的时候,ListView
- Android 获取并显示远程图片 Picasso框架的使用(二)
- Android —— 静态AsyncTask解决内存泄漏