Android ImageView中我们在使用Bitmap加载图片时特别容易造成OOM内存溢出泄露的问题,特别是在像ListView或者RecyclerView这样的控件中大量加载图片,Bitmap内存溢出就更加明显了。
网上有各种说法说可以使用Java虚拟机的垃圾回收器来手动回收Bitmap对象内存,代码类似如下这样:if(headBitmap != null && !headBitmap.isRecycled()){
headBitmap.recycle();
headBitmap = null;
}
System.gc();
其实这些方法并不能真的回收bitmap内存,反而内存依然会不断增加,造成OOM内存溢出问题,甚至如果你在别的界面复用了这个图片,就会造成如下这样的问题,导致程序闪退:
Canvas: trying to use a recycled bitmap
所以我们在使用本地图片生成Bitmap对象的时候,要尽量避免bitmap对象造成的OOM现象,可以直接使用如下方法生成一个Bitmap对象,就可以完全避免内存OOM了,代码如下:/**
* 使用SD卡上的图片
*/
public Bitmap useTheImage(String imageUrl) {
File file = new File(imageUrl);
if (!file.exists()) {
return null;
}
BitmapFactory.Options bfOptions = new BitmapFactory.Options();
bfOptions.inDither = false;
bfOptions.inPurgeable = true;
bfOptions.inInputShareable = true;
bfOptions.inTempStorage = new byte[16 * 1024];
bfOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bfOptions.outWidth = 130;
bfOptions.outHeight = 210;
FileInputStream fs = null;
try {
fs = new FileInputStream(file);
if (fs != null)
return BitmapFactory.decodeStream(fs, null, bfOptions);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fs != null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
以上的代码,最主要的是需要使用BitmapFatory中的的decodeStream方法,如下:decodeStream(@Nullable InputStream is, @Nullable Rect outPadding,
@Nullable Options opts)
其中InputStream是文件的字节流
Rect可以为空,不用管
而Options这个参数必须要添加,不然依然会造成Bitmap内存溢出问题的
Bitmap.Config.RGB_565这些参数也能有效的解决Bitmap内存的耗费,因为它是通过降低一点图片的清晰度来节省虚拟机内存,所以建议也用上。
为什么BitmapFactory.decodeStream方法可以避免bitmap内存溢出呢?
因为使用了decodeStream方法之后,处理图片加载就会用本地内存来处理,所以耗费的内存就很小了,也能及时回收掉,所以至今都没有内存泄露的问题。
上面同样的方法,小编使用BitmapFactory的decodeFileDescriptor方法,就会在RecyclerView加载到10多页之后Bitmap就内存泄露了,代码如下:decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
validate(opts);
所以小编不建议使用decodeFileDescriptor方法来加载本地图片!
来源网站:太平洋学习网,转载请注明出处:http://www.tpyyes.com/a/android/991.html