Java 第二次创建位图时出现内存不足异常
在我的android应用程序中,我需要拍照。第一张图片很好,可以上传到服务器,这样就可以通过电子邮件发送给用户。那很好。然而,当我想上传第二张图片时,它会显示内存不足异常。我不知道为什么,但不知怎么的,的确如此 我的logcat输出可在此pastebin链接中找到: 我处理图像的代码如下所示: 首先检查手机是否有摄像头:Java 第二次创建位图时出现内存不足异常,java,android,exception,bitmap,out-of-memory,Java,Android,Exception,Bitmap,Out Of Memory,在我的android应用程序中,我需要拍照。第一张图片很好,可以上传到服务器,这样就可以通过电子邮件发送给用户。那很好。然而,当我想上传第二张图片时,它会显示内存不足异常。我不知道为什么,但不知怎么的,的确如此 我的logcat输出可在此pastebin链接中找到: 我处理图像的代码如下所示: 首先检查手机是否有摄像头: Camera cam = Camera.open(); if (cam != null) { if (savedInstanceState != nul
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);
}
}
单击“捕捉”按钮时,将触发以下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);
_mPhoto.recycle();
}
}
}
拍摄照片时,将触发result方法:
@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();
}
}
}
}
错误应该在最后一个方法中,因为当我在cameramode中并且想要返回到我的应用程序时,错误就发生了。
如何修复此错误?我错过什么了吗
编辑:
在函数:OnActivityResult中添加了代码。
创建了一个临时对象作为解决方案之一。可惜这无助于解决错误
内存不足异常错误发生在以下行:
_mPhoto = android.provider.MediaStore.Images.Media.getBitmap(cr, _mUri);
您不应该创建位图并使用它,而不保留对它的引用,因为您必须释放它以实现良好的内存管理 你所做的:
_mPhoto = Bitmap.createScaledBitmap(
BitmapFactory.decodeFile(PATH_TO_PHOTO, o),
_mPhoto.getWidth() / scale, _mPhoto.getHeight()
/ scale, false);
太糟糕了!;)
首选:
Bitmap temp = BitmapFactory.decodeFile(PATH_TO_PHOTO, o);
_mPhoto = Bitmap.createScaledBitmap(
temp,
_mPhoto.getWidth() / scale, _mPhoto.getHeight()
/ scale, false);
temp.recycle(); //this call is the key ;)
阅读您的代码时,请记住:“创建的每个位图都必须循环使用,否则它将在某个时候因OOM错误而崩溃”
希望有帮助
您应该阅读更多有关的内容以完全理解;) 我认为你的图像没有被压缩。因为在logcat的第1行中,它指定i/p和o/p,宽度和高度相同。图像未压缩,但我不希望由于质量损失而被压缩?是否要将图像发送到服务器。您还可以将其设置为imageview。尝试注释代码(设置为imageview)并检查它是否有效。我为什么要这样做?然后图像将不再在活动中显示。但是错误还是发生了。我按照你说的做了,但是错误还是发生了。我将用编辑过的部分更新问题:)用你的代码更新问题。你的思维是对的。但不知何故,这个错误并没有解决:(那么可能您的位图太大。请尝试获取首选大小。请参阅上的calculateInSampleSize方法。如果我的位图太大,它应该在第一次尝试创建位图时就失败了,对吗?但事实上,错误发生在第二次。错误发生后,我将进入上一次活动,然后再次进入拍照活动再拍一张照片,一切都很好。当我不压缩位图时,上传时间会变长。当我压缩位图时,上传时间会变短