bitmap加载常用的缓存策略是LruCache和DiskLruCache。一个常备用于内存缓存一个用于存储缓存。LRU是最近最少使用算法。。缓存快满时淘汰最少使用的缓存目标。
- 使用BitmapFactory加载bitmap有decodefile(从文件系统加载),decodeResource(资源),decodeStream(输入流),decodeByteArray(字节数组)
- 使用bitmapFactory.options缩放图片,主要修改inSampleSIze参数,大于1才能有缩小效果,缩放后的指数一般是2的指数(不够就向下取整)。
- 1)将BitmapFacctory.Options的injustDecodeBounds设为true。2)将BitmapFacctory.Options取到原始宽高。 3)根据采样规则结合view大小计算inSampleSIze。4)将BitmapFacctory.Options的injustDecodeBounds设为false,重新加载。
代码链接
public class ImageResizer {
private static final String TAG = "ImageResizer";
public ImageResizer() {
}
public Bitmap decodeSampledBitmapFromResource(Resources res,
int resId, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public Bitmap decodeSampledBitmapFromFileDescriptor(FileDescriptor fd, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFileDescriptor(fd, null, options);
}
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
if (reqWidth == 0 || reqHeight == 0) {
return 1;
}
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
Log.d(TAG, "origin, w= " + width + " h=" + height);
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
Log.d(TAG, "sampleSize:" + inSampleSize);
return inSampleSize;
}
}
4.LruCache为了兼容2.2建议使用v4包的,而不是系统3.1版本。LruCache是一个泛型类内部采用LinkedHashMap强引用来存储.memoryCache可以get,put来获取添加对象那个。
5.DiskLruCache获取代码不是从sdk获取。
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
用open方式创建,directory磁盘sd卡缓存目录/sdcard/andorid/data/package_name/cache目录。appVersion和valueCount一般设为1,maxSize缓存总大小。
6.DiskLruCache通过Editor来完成缓存添加操作,因为http的url有可能要特殊字符,一般转换成对应的md5值作为key,然后在网络下载图片时写入文件系统上,最后要通commit来提交。
7.DiskLruCache为了解决FileInputStream是一种有序文件流要通过文件获取到BitmapFactory.decodeFileDescriptor来加载缩放的图片。
8.ImageLoader主要给lv和gv设置setOnScrollListener,在onScrollStateChange判断是否在滑动状态给他一个标志。当然最后还可以通过开启硬件加速来完成卡顿问题。