本章的主题是Bitmap的加载和Cache,主要包含三个方面的内容。首先讲述如何有效的加载一个Bitmap,这是一个很有意义的话题,由于Bitmap的特殊性以及Android对单个应用所施加的内存限制,比如16MB,这就导致加载Bitmap的时候很容易的出现内存溢出。下面这个异常在开发中应该时常遇到:
java.lang.OutofMemoryError:bitmap size exceeds VM budget
因此如何高效的加载Bitmap是一个很重要也很容易被开发者忽视的问题。
一、Bitmap的高效加载
获取采样率的步骤
将上面的4个流程用程序来实现,就产生了下面的代码:
public static Bitmap decodeSampleBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
//设置只请求大小不加载标记
options.inJustDecodeBounds = true;
//获取到图片的宽高
BitmapFactory.decodeResource(res, resId, options);
//计算采样率
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
//重置标记,加载图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
//计算采样率,逻辑就是采样后的宽和高都大于请求的宽高,采样率*2。直到满足条件返回
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
int width = options.outWidth;
int height = options.outHeight;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
int halfHeight = height / 2;
int halfWidth = width / 2;
while (halfHeight / inSampleSize >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
Log.d(TAG,"采样率 = " + inSampleSize);
return inSampleSize;
}
有了上面的两个方法,实际使用的时候就很简单,比如ImageView所期望的大小是100*100像素,这个时候就可以通过如下方式高效地加载并显示图片:
mImageView.setImageBitmap(decodeSampleBitmapFromResource(getResources(),R.drawable.ic_launcher,100,100));
除了BitmapFactory的decodeResource方法,其它三个decode系列的方法也是支持采样加载的,并且处理方式也是类似的,但是decodeStream方法稍微有点特殊,这个会在后续内容详细介绍。
二、Android中的缓存策略
1、LruCache
LruCache是android3.1所提供的一个缓存类,通过support-v4兼容包可以兼容到早期的Android版本。
Lr