http://blog.csdn.net/yaya_soft/article/details/40785875
android中图片的三级缓存cache策略(内存/文件/网络)
现在android应用中不可避免的要使用图片,有些图片是可以变化的,需要每次启动时从网络拉取,这种场景在有广告位的应用以及纯图片应用(比如百度美拍)中比较多。
现在有一个问题:假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量。在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响。当然,我想,向百度美拍这样的应用,必然也有其内部的图片缓存策略。总之,图片缓存是很重要而且是必须的。
2.图片缓存的原理
实现图片缓存也不难,需要有相应的cache策略。这里我采用 内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且也把它划到缓存的层次结构中。当根据url向网络拉取图片的时候,先从内存中找,如果内存中没有,再从缓存文件中查找,如果缓存文件中也没有,再从网络上通过http请求拉取图片。在键值对(key-value)中,这个图片缓存的key是图片url的hash值,value就是bitmap。所以,按照这个逻辑,只要一个url被下载过,其图片就被缓存起来了。
关于Java中对象的软引用(SoftReference),如果一个对象具有软引用,内存空间足够,垃 圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高 速缓存。使用软引用能防止内存泄露,增强程序的健壮性。
从代码上来说,采用一个ImageManager来负责图片的管理和缓存,函数接口为public void loadBitmap(String url, Handler handler) ;其中url为要下载的图片地址,handler为图片下载成功后的回调,在handler中处理message,而message中包含了图片的信息以及bitmap对象。ImageManager中使用的ImageMemoryCache(内存缓存)、ImageFileCache(文件缓存)以及LruCache(最近最久未使用缓存)会在后续文章中介绍。
http://www.jb51.net/article/38162.htm
做Android应用开发的同学们相信对“缓存”这个词不陌生,缓存可能有多方面的概念,这里大概列举下程序开发的缓存大概有哪些:
-
1.服务端控制缓存
如volley请求库,便是通过服务端的“Cache-Control”和“max-age”来告诉客户端有没有缓存以及缓存的时间,也是推荐的使用方式,但是需要服务端配合,比较灵活。
-
2.客户端直接控制缓存
有些时候不需要服务端来支持的话,客户端可以直接做一层缓存,思路就是请求之后把数据缓存在本地,最常见的是直接以文件缓存在本地就好了,当然你可以缓存在本地的sqlite,以sqlite文件的形式缓存数据处理更灵活点,然后客户端自己处理缓存的时间,过期则直接清除数据。对于一些不太经常变化的页面,采用这种缓存可以减少客户端流量,同时减少服务器并发量。
对于一些新闻类或者timeline这种,数据变化是非常频繁的,针对这种情况可能就不太适合设置缓存时间,这种情况可以考虑让页面每次进来都会自动刷新一次以获取最新数据,如果网络不好或者断开时可以直接读取本地缓存,增加用户体验。当然如果想要更复杂的处理可以配合时间来判断当前页面要不要刷新。
picasso-强大的Android图片下载缓存库
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0731/1639.html
Volley 讲解 :http://blog.csdn.net/jxxfzgy/article/details/44022435
Android中关于Volley的使用(八)缓存机制的深入认识( http://blog.csdn.net/linmiansheng/article/details/23023573?utm_source=tuicool )
android Gridview图片异步加载的要领
关于GridView或者是ListView异步加载图片的文章数不胜数,总结起来就是:
1.高效率的缓存机制(文件缓存和LruCache并用)
2.图片的压缩方式,尽可能节省内存
3.UI刷新的频率
其中第三点,UI刷新的频率指的是在滑动过程中,当图片加载完,ImageView都会有setImageBitmap这种更新UI的事件,如果在同一时间内有好几个线程同时完成图片的加载,由于是在滚动过程中,会造成轻微的卡顿。
解决的办法一般是在滑动的时候暂停加载,当滑动停止再继续完成加载,或者是滑动比较快的时候暂停加载,滑动慢下来了再去加载,我比较喜欢第二种,不过你需要得到这个滑动速度,如何获得请看这篇文章:
但是还有一点被忽略的是开启的线程数目其实也会影响到这个流畅度,线程数目并不是越多越好,如果一下子开启了50个线程,那么这50个线程如果完成时间差别不大,也会导致UI刷新频率过高。一般我们使用线程池来管理线程的数目。过多的线程数目不仅会直接导致cpu负载过高,还会因为UI刷新频繁影响UI线程的流畅性。
实际上,一般线程池的数目在小于5比较合适,而且我还发现如果线程数目在3以下,上面提到的滑动比较快的时候去暂停加载这个方案是可以弃用的,因为线程数目较少(比如线程池大小为2),滑动再快同时也只会刷新两张图片。所以最好的解决方案是采用容量较小的线程池,同时不再考虑滚动(或者滚动过快)时是否加载的问题,如果你还是一定要考虑,那暂停加载的时机也最好是速度较大的时候。总之在线程池数目与暂停加载之间找到一个平衡点吧。
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0919/1694.html