【问题标题】:Bitmap URI stays the same Android Out Of Memory Exception位图 URI 保持不变 Android Out Of Memory Exception
【发布时间】:2013-11-04 11:35:18
【问题描述】:

我有一个问题,我正在拍摄一张图片并将其上传到服务器。第一次,这一切都很好。 但是我第二次拍照时,我在这一行遇到了内存不足的异常:

_mPhoto = android.provider.MediaStore.Images.Media
                        .getBitmap(cr, _mUri);

如果我正在调试 _mUri,第一次和第二次是一样的。我认为这不应该..

我收到此错误:http://pastebin.com/uVduy3d9

这是我用来拍照的3种方法:

首先检查手机是否有摄像头:

Camera cam = Camera.open();
    if (cam != null) {
        if (savedInstanceState != null
                && savedInstanceState.getBoolean("Layout")) {
            setContentView(R.layout.registration_edit);
            initializeAccountDetails((User) savedInstanceState
                    .getSerializable(EXTRA_MESSAGE));
            inAccountDetails = true;
        } else {
            setContentView(R.layout.step_4);
            ((Button) findViewById(R.id.snap)).setOnClickListener(this);
            ((Button) findViewById(R.id.rotate)).setOnClickListener(this);
            cam.stopPreview();
            cam.release();
            cam = null;
        }
    } else {
        if (savedInstanceState != null
                && savedInstanceState.getBoolean("Layout")) {
            setContentView(R.layout.registration_edit);
            initializeAccountDetails((User) savedInstanceState
                    .getSerializable(EXTRA_MESSAGE));
            inAccountDetails = true;
        } else {
            setContentView(R.layout.step_4b);
        }
    }

当点击按钮 Snap 时,会触发以下 onClick 事件:

@Override
public void onClick(View v) {
    if (v.getId() == R.id.snap) {
        File directory = new File(Environment.getExternalStorageDirectory()
                + "/BandenAnalyse/Images/");
        if (directory.exists()) {
            Intent i = new Intent("android.media.action.IMAGE_CAPTURE");
            File f = new File(Environment.getExternalStorageDirectory(),
                    "/BandenAnalyse/Images/IMG_" + _timeStamp + ".jpg");
            _mUri = Uri.fromFile(f);
            i.putExtra(MediaStore.EXTRA_OUTPUT, _mUri);
            startActivityForResult(i, TAKE_PICTURE);
        } else {
            directory.mkdir();
            this.onClick(v);
        }
    } else {
        if (_mPhoto != null) {
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            _mPhoto = Bitmap.createBitmap(_mPhoto, 0, 0,
                    _mPhoto.getWidth(), _mPhoto.getHeight(), matrix, true);
            ((ImageView) findViewById(R.id.photo_holder))
                    .setImageBitmap(_mPhoto);
        }
    }
}

当照片被拍摄时,结果方法将被触发:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
    case TAKE_PICTURE:
        if (resultCode == Activity.RESULT_OK) {
            getContentResolver().notifyChange(_mUri, null);
            ContentResolver cr = getContentResolver();
            try {
                _mPhoto = android.provider.MediaStore.Images.Media
                        .getBitmap(cr, _mUri);

                Display display = getWindowManager().getDefaultDisplay();
                Point size = new Point();
                display.getSize(size);
                int width = size.x;
                int scale = _mPhoto.getWidth() / width;
                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inSampleSize = 8;
                Debug.out(PATH_TO_PHOTO);
                Bitmap temp = BitmapFactory.decodeFile(PATH_TO_PHOTO, o);

                _mPhoto = Bitmap.createScaledBitmap(
                                            temp,
                                            _mPhoto.getWidth() / scale, _mPhoto.getHeight()
                                                    / scale, false);

                temp.recycle();
                ((ImageView) findViewById(R.id.photo_holder))
                        .setImageBitmap(_mPhoto);
            } catch (Exception e) {
                Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }
}

【问题讨论】:

  • 如果使用大于或等于 11 的 API,则在清单中使用“useLargeheapSpace=true”。
  • 看来你有内存泄漏。您可以使用 Eclipse 中的 Memory Analyzer 工具来查找它。我建议您在设置位图后添加 _mPhoto.recycle() 并且您将 ((ImageView) findViewById(R.id.photo_holder)) 定义为类级别的 ImageView 变量,以防止每次都创建新实例
  • 我也支持低于 11 的 api。高于和等于 11 的作品现在非常好感谢@AliImran
  • @Mohamed_AbdAllah 我现在要试试 :)!
  • @Mohamed_AbdAllah 当我回收 _mPhoto 时,它仍然会出现错误,现在要使用内存分析器

标签: android exception bitmap uri out-of-memory


【解决方案1】:

我想我必须补充一下:

android:largeHeap="true"

到我的清单文件。这让我可以多次这样做。

【讨论】:

  • 这是我在上面的评论中建议你的。
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多