在图片使用较多的应用中,每个图片的展示至少要Decode一次。由于图片比较占内存,所以内存分配/释放的频率会提高。也就是由于allocation 导致的GC(GC_FOR_ALLOC)出现的频率会很高。众所周至GC可能会导致UI卡顿,所以说图片多的应用非常容易出现卡顿。
为了解决这个问题,Android中提供了Bitmap Pool的概念 (参考资料:Re-using Bitmaps)。
使用Bitmap Pool的一种方式是使用inBitmap()。
话不多说,直接看代码。
Bitmap bitmapOne = BitmapFactory.decodeFile(filePathOne);
imageView.setImageBitmap(bitmapOne);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePathTwo, options);
if (canUseInBitmap(bitmapOne, options)) {
//判断是否可用inBitmap
options.inMutable = true;
options.inBitmap = bitmapOne;
}
options.inJustDecodeBounds = false;
Bitmap bitmapTwo = BitmapFactory.decodeFile(filePathTwo, options);
imageView.setImageBitmap(bitmapTwo);
如何判断是否能够设置使用inBitmap()呢?就得看官方给的限制条件:
- API 11-18 要求Bitmap大小完全一致, 并且inSampleSize必须是1 官方文档
- API 19+ (Android 4.4及以后) 要求被重用的Bitmap所占大小要大于等于要加载的Bitmap
判断是否能够使用inBitMap()
public static boolean canUseInBitmap(Bitmap reuseBitmap, BitmapFactory.Options targetOptions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 4.4+
int width = targetOptions.outWidth / targetOptions.inSampleSize;
int height = targetOptions.outHeight / targetOptions.inSampleSize;
int byteCount = width * height * getDim(reuseBitmap.getConfig());
try {
return byteCount <= reuseBitmap.getAllocationByteCount();
} catch (NullPointerException e) {
return byteCount <= reuseBitmap.getHeight() * reuseBitmap.getRowBytes();
}
}
// API 18 前
return reuseBitmap.getWidth() == targetOptions.outWidth
&& reuseBitmap.getHeight() == targetOptions.outHeight
&& targetOptions.inSampleSize == 1;
}
private static int getDim(Bitmap.Config config) {
if (config == null) {
return 4;
}
switch (config) {
case ALPHA_8:
default:
return 1;
case RGB_565:
case ARGB_4444:
return 2;
case ARGB_8888:
return 4;
}
}
注意事项:
- 如果尝试重用不可被复用Bitmap,decode方法会返回null并抛出IllegalArgumentException。
- 被复用的Bitmap必须要求设置为mutable,decode返回的新的bitmap也是mutable。
最后,一个好消息 and 一个坏消息:
好消息:
Glide, Fresco等比较新的图片加载库,已经完全支持inBitmap了,一般情况下不需要手动的配置。
坏消息:
目前我们产品中使用的UIL不支持inBitmap。
网友评论