由于Bitmap的特殊性以及Android对单个应用所施加的内存限制,比如16M,这导致加载Bitmap的时候很容易出现内存溢出。比如以下场景:

java.lang.OutofMemoryError:bitmap size exceeds VM budget

Android中常用的缓存策略也是很有意思,缓存策略一个通用的思想,可以用到很多场景中,比如在实际开发中经常需要用到Bitmap做缓存。通过缓存策略,我们不需要每次都从网络上请求图片或者从存储设备中加载图片,这样就极大地提高了图片的加载效率以及产品的用户体验。目前比较常用的缓存策略是LruCache和DiskLruCache,其中LruCache常被用做内存缓存,而DiskLruCache用做存储缓存。Lru是Least Recently Used的缩写,即最近最少使用算法,这种算法的核心思想:当缓存快满时,会淘汰近期最少使用的缓存目标,很显然Lru算法的思想是很容易被接受的。

Bitmap的高效加载

Bitmap在Android中指的是一张图片,可以是png格式也可以是jpg等其他常见的图片格式。BitmapFactory类提供了四类方法:decodeFile、decodeResource、decodeStream和decodeByteArray,分别用于支持从文件系统、资源、输入流以及字节数组中加载出一个Bitmap对象,其中decodeFile和decodeResource又间接调用了decodeStream方法,这四类方法最终是在Android的底层实现的,对应着BitmapFactory类的几个native方法。

如何高效地加载Bitmap呢,其实核心思想也简单,那就是采用BitmapFactory.Options来加载所需尺寸的图片。主要是用到它的inSampleSize参数,即采样率。当inSampleSize为1时,采样后的图片大小为图片的原始大小,当inSampleSize大于1时,比如为2,那么采样后的图片其宽/宽均为原图大小的1/2,而像素数为原图的1/4,其占有的内存大小也为原图的1/4。从最新官方文档中指出,inSampleSize的取值应该是2的指数,比如1、2、4、8、16等等。

通过采样率即可有效地加载图片,那么到底如何获取采样率呢,获取采样率也很简单,循序如下流程: