应根据实际展示需要,压缩图片,而不是直接显示原图。手机屏幕比较小,
直接显示原图,并不会增加视觉上的收益,但是却会耗费大量宝贵的内存。
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight)
{
// 首先通过 inJustDecodeBounds=true 获得图片的尺寸
final 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);
}
使用完毕的图片,应该及时回收,释放宝贵的内存。
Bitmap bitmap = null;
loadBitmapAsync(new OnResult(result){
bitmap = result;
});
...使用该 bitmap...
// 使用结束,在 2.3.3 及以下需要调用 recycle()函数,在 2.3.3 以上 GC 会自动管理,除非你明确不需要再用。
if (Build.VERSION.SDK_INT <= 10) {
bitmap.recycle();
}
bitmap = null;
使用 inBitmap 重复利用内存空间,避免重复开辟新内存。避免了一次内存的分配和回收,从而改善了运行效率
正例:
public static Bitmap decodeSampledBitmapFromFile(String filename, int reqWidth, int reqHeight, ImageCache cache) {
final BitmapFactory.Options options = new BitmapFactory.Options();
BitmapFactory.decodeFile(filename, options);
// 如果在 Honeycomb 或更新版本系统中运行,尝试使用 inBitmap
if (Utils.hasHoneycomb()) {
addInBitmapOptions(options, cache);
}
return BitmapFactory.decodeFile(filename, options);
}
private static void addInBitmapOptions(BitmapFactory.Options options, ImageCache cache) {
// inBitmap 只处理可变的位图,所以强制返回可变的位图
options.inMutable = true;
if (cache != null) {
Bitmap inBitmap = cache.getBitmapFromReusableSet(options);
if (inBitmap != null) {
}
options.inBitmap = inBitmap;
}
}
在使用inBitmap时注意:
1、inBitmap只能在3.0以后使用。2.3上,bitmap的数据是存储在native的内存区域,并不是在Dalvik的内存堆上。
2、在4.4之前,只能重用相同大小的bitmap的内存区域,而4.4之后你可以重用任何bitmap的内存区域,只要这块内存比将要分配内存的bitmap大就可以。
网友评论