android中的内存外异常和Uri位图

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

我有一个应用程序,可以从相机中获取照片并在imageview中显示

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();
        }
    }