本文仅仅是个人学习笔记,如有错误的地方请大家指正,谢谢!
通过BitmapFactor.Options来缩放图片,可以通过设置他的isSampleSize参数,来调整图像的采样率。比如isSampleSize取值为4,那么采样后的图片的长宽像素点个数都为原始图片的1/4,即总的像素个数为1/16。isSampleSize最好设置为2的n次方。如果isSampleSize参数不为2的n次方,系统会向下取整并选择一个最接近的2的n次方。
原始图片的尺寸可以通过以下两个步骤获得:
1.将BitmapFactory.Options的isJustDecodeBounds设置为true,然后加载图片。设置完这个参数后加载图片仅仅是获得图片的尺寸,而不会真正去加载图片,因此这是一个轻量级的操作,不会耗费很长的时间.
2.从Options中的outHeight和outWidth可以得到图片的原始高宽。对于BitmapFactory的四种decodeResource方法,除了decodeStream之外的三种都能够支持采样加载。但是decodeStream在对FileInputStream进行缩放的时候会出现问题。这是因为FileInputStream是一种有序的文件流,decodeStream的调用会影响FileInputStream的位置属性,因此当我们计算好缩放系数之后,再来真正的加载图片的时候decodeStream得到的为null。为了解决这个问题,可以通过decodeFileDescription来加载缩放后的图片。
缓存策略,程序要加载一张图片时,首先在内存中查找,如果没有的话,在sd卡中查找,要是还是没有的话再到网络中去下载。
LRU(Least Recently Used),近期最少使用算法:当缓存满时,优先删除近期最少使用的缓存对象。采用LRU算法的缓存有两种:LruCache和DiskLruCache.LruCache实现了内存缓存,DiskLruCache实现了存储设备缓存。
LruCache是一个泛型类,它内部采用了一个LinkdeHashMap以强引用的方式存储外界的缓存对象,通过get,put方法完成缓存的获取和添加操作。(强引用:直接的对象引用,当内存不足时,宁愿发生OOM错误也不会将其回收。软引用:当一个对象只有软引用存在时,当内存不足时系统会将其回收;弱引用:当一个对象只有若引用存在时,这个对象随时可能被系统回收;虚引用:跟没有引用一样,他不决定对象的生命周期,主要是用来跟踪GC的活动)
DiskLruCache:需要通过open(File directory, int appVersion, int valueCount, long maxSize)方法来创建自身。第一个参数为磁盘缓存在文件系统中的存储路径,第二个参数为app的版本号,当版本号发生变化时DiskLruCache会清空之前的缓存文件。第三个参数为节点对应的数据个数,一般设置为1即可。最后一个参数为缓存区大小。
DiskLruCache的缓存添加操作是通过Editor来完成的,可以通过editor(key)来获取key(由于文件的url可能含有特殊字符,因此在android中一般都是采用url的MD5值作为key)所对应的文件的Editor对象。如果一个缓存正在被编辑,那么editor(key)这个方法返回的将是null,也就是说DiskLruCache不允许同时修改同一个缓存。
DiskLruCache缓存查找,先将url转换为key,之后通过DiskLruCahce.get(key)方法获取一个Snapshot,然后通过Snapshot的getInputStream方法获取缓存文件的文件输入流,之后decodeBitmap就能得到缓存的图片了。
解决因为View复用导致的图片错位问题:在为imageView设置bitmap之前核对两者的url是否相同,相同才为其设置bitmap。
优化列表卡顿:通过异步的方式加载图片,而且在滑动的过程中不加载图片。通过在onScrollStateChange中获取滑动状态。