android中的内存外异常和Uri位图
我有一个应用程序,可以从相机中获取照片并在imageview中显示android中的内存外异常和Uri位图,android,bitmap,Android,Bitmap,我有一个应用程序,可以从相机中获取照片并在imageview中显示 Uri bitmapPictureUri = intent.getParcelableExtra(TaskActivity.PHOTO); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), bitmap
Uri bitmapPictureUri = intent.getParcelableExtra(TaskActivity.PHOTO);
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), bitmapPictureUri);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int nh = (int) (bitmap.getHeight() * (512.0 / bitmap.getWidth()));
bitmapPicture = Bitmap.createScaledBitmap(bitmap, 512, nh, true);
WeakReference<Bitmap> bm = new WeakReference<Bitmap>(bitmap);
WeakReference<Bitmap> bm2 = new WeakReference<Bitmap>(bitmapPicture);
picture.setImageBitmap(bm2.get());
有什么办法可以避免这个问题吗?我尝试使用simpleSize、weakreferences、bitmap.recycle。System.gc和nothing。这是我的做法。您必须使用我在下面添加的decodeUri方法从URI获取位图
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(data != null){
Uri dataUri = data.getData();
Bitmap bitmap;
try {
bitmap = decodeUri(dataUri);
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
此方法将优化内存,您的异常将不再发生
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 140;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
}
注:我在某处读到的decodeUri方法不是我的代码。干杯 使用imageloader类。这将解决位图内存不足异常问题
我通过以下方式解决我的问题:
protected void onDestroy() {
super.onDestroy();
bitmapPicture.recycle();
bitmap.recycle();
unbindDrawables(findViewById(R.id.picture_measure_picture));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
我打赌你在“活动销毁”阶段没有正确回收/缓存映像。在“活动销毁”阶段释放缓存内存。应该避免直接重定向到外部引用的答案。如果trickI知道,你应该将答案标记为已接受,但我必须等待接受
protected void onDestroy() {
super.onDestroy();
bitmapPicture.recycle();
bitmap.recycle();
unbindDrawables(findViewById(R.id.picture_measure_picture));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}