12.1 Bitmap的高效加载
BitmapFactory类提供了四类方法:decodeFile、decodeResource、decodeStream和decodeByteArray,分别用于支持从文件系统、资源、输入流以及字节数组中加载出一个Bitmap对象,其中decodeFile和decodeResource又间接调用了decodeStream方法,这四类方法最终是在Android的底层实现的,对应着BitmapFactory类的几个native方法。
如何高效地加载Bitmap 呢?其实核心思想也很简单,那就是采用BitmapFactory.Options来加载所需尺寸的图片。通过BitmapFactory.Options来缩放图片,主要是用到了它的inSampleSize参数,即采样率。
通过采样率即可有效地加载图片,那么到底如何获取采样率呢?获取采样率也很简单,遵循如下流程:
- 将BitmapFactory.Options的inJustDecodeBounds参数设为true并加载图片。
- 从BitmapFactory.Options 中取出图片的原始宽高信息,它们对应于outWidth 和outHeight参数。
- 根据采样率的规则并结合目标View的所需大小计算出采样率inSampleSize。
- 将BitmapFactory.Options的inJustDecodeBounds 参数设为false, 然后重新加载图片。
这里说明一下inJustDecodeBounds参数,当此参数设为true时,BitmapFactory 只会解析图片的原始宽/高信息,并不会去真正地加载图片,所以这个操作是轻量级的。
12.2 Android中的缓存策略
缓存策略:内次缓存+存储缓存。当应用打算从网络上请求一张图片时,程序首先从内存中去获取,如果内存中没有那就从存储设备中去获取,如果存储设备中也没有,那就从网络上下载这张图片。
一般来说, 缓存策略主要包含缓存的添加、获取和删除这三类操作。删除缓存目前常用的一种缓存算法是LRU(Least Recently Used),LRU是近期最少使用算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象。采用LRU算法的缓存有两种:LruCache和DiskLruCache,LruCache用于实现内存缓存,而DiskLruCache则充当了存储设备缓存。
12.2.1 LruCache
LruCache它是一个泛型类,它内部采用一个LinkedHashMap,当强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作,当缓存满时,LruCache会移除较早使用的缓存对象,然后再添加新的缓存对象。
- 强引用:直接的对象引用
- 软引用:当一个对象只有软引用存在时,系统内存不足时此对象会被gc回收。
- 弱引用:当一个对象只有弱引用存在时,此对象会随时被gc回收。
LruCache是线程安全的,因为用到了LinkedHashMap。
sizeOf
计算缓存对象的大小LruCache.get(key)
获取一个缓存对象LruCache.put(key, bitmap)
添加一个缓存对象LruCache.remove
删除一个指定的缓存对象。entryRemoved
移除旧缓存时会调用- 可以进行一些资源回收工作
12.2.2 DiskLruCache
DiskLruCache用于实现存储设备缓存,即磁盘存储,它通过将缓存对象写入文件系统从而实现缓存的效果。
- DiskLruCache 的创建
open
- DiskLruCache 的缓存添加
edit
commit
abort
- DiskLruCache的缓存查找和删除
get
remove
delete
12.2.3 ImageLoader的实现
一般来说,一个优秀的ImageLoader应该具备如下功能:
- 图片的同步加载
- 图片的异步加载
- 图片压缩
- 内存缓存
- 磁盘缓存
- 网络拉取
实现步骤:
- 图片压缩功能的实现
- 根据宽高修改BitmapFactory.Options采样率
- 内存缓存和磁盘缓存的实现
- LruCache和DiskLruCache
- 同步加载和异步加载接口的设计
- 使用线程池和Handler
12.3 ImageLoader的使用
12.3.1 照片墙效果
12.3.2 优化列表的卡顿现象
- 不要在getView中执行耗时操作。
- 控制异步任务的执行频率。可以考虑在列表滑动的时候,停止加载图片,尽管这个过程是异步的,等列表停下来以后在加载图片仍然可以获得良好的用户体验。
- 开启硬件加速可以解决莫名的卡顿问题,通过设置
android:hardwareAccelerated = "true"
即可为Activity开启硬件加速。