带 inJustDecodeBounds=true 的 OutOfMemory 解码图像

Posted

技术标签:

【中文标题】带 inJustDecodeBounds=true 的 OutOfMemory 解码图像【英文标题】:OutOfMemory decoding image with inJustDecodeBounds=true 【发布时间】:2012-12-29 09:31:09 【问题描述】:

在我的 android 应用程序中尝试解码来自相机的图像时,我不断收到 OutOfMemory 异常。有很多问题可以解决这个问题,但我的情况特别奇怪,因为即使只是尝试使用options.inJustDecodeBounds=true 获得界限,我也会遇到异常。

这是启动相机的代码:

protected void takePicture() 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    File image = new File(IMAGE_PATH, "camera.jpg");
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
    startActivityForResult(takePictureIntent, 0);

下面是触发异常的代码:

protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    if (resultCode == RESULT_OK )  
        String rawImageName = new String(IMAGE_PATH + "/camera.jpg");

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(rawImageName); // The exception is thrown here
            .
            .
            .
    

我尝试使用非常高的采样率对图像进行解码,但仍然出现相同的异常:

options.inSampleSize = 20;
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap photo = BitmapFactory.decodeFile(rawImageName); // Again the exception

除此之外,应用程序似乎运行正常并且有足够的可用内存。我可以在图库应用程序中正确打开图像。将图像移动到其他目录没有帮助。任何想法可能导致它?使用inJustDecodeBounds = true 解码时可能导致异常的原因是什么?

【问题讨论】:

向我们展示您的堆栈跟踪。 我认为你应该看看这个链接:developer.android.com/training/displaying-bitmaps/… 好吧,这恰好是一个愚蠢的复制粘贴错误。应该删除问题吗?对别人有什么价值吗? 【参考方案1】:

您需要将选项传递给解码调用:

BitmapFactory.decodeFile(rawImageName, options);

【讨论】:

哦,我的愚蠢!这就是复制粘贴代码时发生的情况。 Grrr 几个小时把我的头发拉出来!!!【参考方案2】:
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = 4; // 1/4
o2.inPurgeable = true;
Bitmap b=BitmapFactory.decodeFile(imagePath,o2);

试试这个。并在使用后调整图像大小并使位图对象为空。 给System.gc();打电话,它不会调用gc,但会给出提示。 也不要制作很多位图对象。重复使用相同的位图对象,并在使用后使其为空。

【讨论】:

在位图上使用 recycle() 而不是 gc。 GC 可能不会立即释放内存。见mobi-solutions.blogspot.com/2010/08/… 和***.com/questions/3823799/… 是的,你是对的。如果您不再使用位图对象,请回收它们。 调用 System.gc() 确实是一种应该避免的反模式。您可以在网上找到很多关于此的文档。总而言之,它尖叫着“损坏的代码”,它不能保证做任何事情,它可能会减慢你的代码速度,因为你可能会开始一个完整的 GC 周期。始终避免使用 System.gc()。

以上是关于带 inJustDecodeBounds=true 的 OutOfMemory 解码图像的主要内容,如果未能解决你的问题,请参考以下文章

BitmapFactory.Options 处理OOM

android 自定义的小工具类获取图片和视频的缩微图

Android ImageView setImageBitmap 不显示图片

Android中BitmapFactory.Options详解

你能解释一下这段代码的作用吗?

android在不加载图片的前提下获得图片的宽高