需求
最近在项目中做一个图片显示的功能,需求是:在界面显示头像,如果用户没有设置图像就显示我们自定义的图片.
实现
由于我们的项目有点老,没有用到一些最新的技术,所以全部自己实现.
图片加载的策略: 三级缓存
1.优先从内存缓存中取图片,显示
2.缓存没有,加载本地的图片
3.本地没有,去网络拉取图片,拉取成功,显示
4.拉取失败,生成自定义图片,显示
整个加载策略就是这样.
实现:
1.缓存图片可以用一个集合来保存,这里我使用的是HashMap<int id,SoftReference<Bitmap>map>
,使用软引用,防止OOM.
2.加载本地,很简单
3.去网络拉取
需要注意的是,在没有网络的时候,加判断(优先从网络拉的时候,没网络需要走1,2,4步骤)
以上步骤就可以实现了一个简单的图片的三级缓存.
问题:
1.Bitmap recycle
调试的时候,某些图片老师显示不出来,很奇怪,后面debug,发现由于缓存的bitmap过多(群列表界面,很多头像),但是一些bitmap被recycled掉了,在显示图片的时候,判断`if(!bitmap.isRecycled())`
2.synchronized 关键字
将bitmap加入缓存的时候,记得加上synchronized,防止异常,我偶尔出现过,头像显示不正常的时候,加上之后就OK了!
优化
在进入群详情的时候,加载图片慢
第一次进入群详情界面,缓存肯定是没有的,很多头像都的去本地加载,IO影响加载效率,显示比微信慢很多,后面有待优化
引用类型
java中是JVM负责内存的分配和回收,这是它的优点(使用方便,程序不用再像使用c那样操心内存),但同时也是它的缺点,不够灵活
强引用
我们大部分引用实际上都是强引用,垃圾回收器绝不会回收它。当内存空 间不足,Java虚拟机会抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题,这也是我们需要防止OOM的原因.
软引用
软引用的特点就是如果内存空间足够,垃圾回收器就不会回收它,否则就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用,可以通过SoftReference,ReferenceQueue来使用.
作用:用来缓存一些对内存敏感的东西.
弱引用
虚引用与软应用的区别就是,不管内存充足与否,在线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
虚引用
引用”顾名思义,就是形同虚设,虚引用并不会决定对象的生命周期,在任何时候都可能被垃圾回收器回收。
作用:主要用来跟踪对象被垃圾回收器回收的活动。