关键词:Bitmap / Cache / 图片加载 / 采样率 / ImageLoader /
本次笔记梳理的内容是 Bitmap 的加载和 Cache。加载 Bitmap 需要注意的问题有防止内存溢出、如何高效地加载 Bitmap 等等,对于常用的缓存策略,实际开发中,我们需要用 Bitmap 做缓存,通过缓存我们不需要每次都从网络上请求图片或者从存储设备中加载图片,极大提高图片的加载效率以及用户体验。
目前常用的缓存策略有:LruCache 和 DiskLruCache,分别对应着 内存缓存 和 存储缓存,最近最少使用算法:当缓存快满的时候,淘汰近期最少使用的缓存目标;
1. Bitmap #
- BitmapFactory 类提供了四类方法:decodeFile、decodeResource、decodeStream 和 decodeByteArray,分别用于支持从 文件系统、资源、输入流 和 字节数组 中加载出一个 Bitmap 对象;
- 高效的加载 Bitmap,采用 BitmapFactory.Options 来加载所需尺寸的图片,通过 BitmapFactory.Options 可以按一定 采样率 来加载缩小后的图片;
- 比如, ImageView 的大小是 100 x 100 像素,而图片的原始大小为 200 x 200,那么只需要将采样率 inSampleSize 设为 2 即可。
- Bitmap 中使用了线程池和 Handler;(如果直接采用普通的线程去加载图片,随着列表的滑动可能会产生大量的线程,不利于整体的效率的提升,选择线程池和 Handler 来提供 ImageLoader 的并发能力和访问 UI 的能力。)
- 5.
2. 缓存策略 #
- 流量对于手机用户来说是一种宝贵的资源,除了 wifi,流量是要收费的,应用开发中不能过多的消耗用户的流量,为了避免这个问题,缓存机制便必不可少了;
- 程序会先从内存中去获取,如果内存中没有就从存储设备中去获取,如果存储设备中也没有,就从网络上去下载这张图片;(该缓存策略不仅仅适用于图片,也适用于其它文件)
- 一般来说,缓存策略包括三种操作:缓存的添加、获取 和 删除;
- 采用 URL 算法的缓存有两种:LruCache 和 DiskLruCache,LruCache 用于实现内存缓存,而后者充当了存储设备缓存,将二者结合可以实现一个具有很高实用价值的 ImageLoader;
关于 LruCache 需要知道的几点:
- 是一个泛型类,内部采用了一个 LinkedHashMap 以强引用的方式存储外界的缓存对象,其提供了 get 和 put 方法来完成缓存的获取和添加操作,当缓存满的时候,LruCache 会移除较早使用的缓存对象,然后再添加新的缓存对象;
- LruCache 是线程安全的;
LruCache 是 Android 的源码的一部分了;
- 强引用:直接的对象引用;
- 软引用:当一个对象只有软引用存在的时候,系统内存不足时此对象会被 gc 回收;
- 弱引用:当一个对象只有弱引用的时候,此对象会随时被 gc 回收;
关于 DiskLruCache 需要知道的几点:
- DiskLruCache 用于实现存储设备缓存,即磁盘缓存;
- DiskLruCache 通过将缓存对象写入文件系统从而实现缓存的效果;
- DiskLruCache 不属于 Android SDK 的一部分;
- DiskLruCache 提供了 open 方法用于创建自身;
- DiskLruCache 的缓存添加的操作是通过 Editor 完成的,Editor 表示一个缓存对象的编辑对象;
- 可以通过 edit() 来获取 Editor 对象;
- 如果这个缓存正在被编辑,那么 edit() 会返回 null,即 DiskLruCache 不允许同时编辑一个缓存对象;
3. ImageLoader #
一个优秀的 ImageLoader 应该具有的功能:
- 图片的同步加载
- 图片的异步加载
- 图片压缩
- 内存缓存
- 磁盘缓存
- 网络拉取
其中内存缓存和磁盘缓存是 ImageLoader 的核心,也是 ImageLoader 的意义所在,这两级缓存极大提高了程序的效率并且有效地降低了对用户所造成的流量消耗,只有当这两级缓存都不可用的时候才会尝试从网络中拉取图片。
End.
Note by HF.
Learn from 《Android 开发艺术探索》