【问题标题】:OutOfMemoryError using bitmap setImageUri [duplicate]OutOfMemoryError 使用位图 setImageUri [重复]
【发布时间】:2012-11-30 11:40:21
【问题描述】:

可能重复:
Android: Strange out of memory issue while loading an image to a Bitmap object
OutOfMemoryError: bitmap size exceeds VM budget :- Android

我有一个应用程序,用户可以拍照或使用画廊中已有的照片,并在将新闻保存在数据库中后附加到新闻(我只是保存图像路径内容:/ / ...) ,我在 ListView 中显示所有新闻,并带有图像标题和日期。要在适配器中显示图像,我正在使用以下内容:

...

image.setImageURI(null);
System.gc();            
image.setImageURI(Uri.parse(noticia.getIMAGEM()));

...

然而即使使用 System.gc();每个加载的新图像都在获取

12-12 14:59:37.239: E / AndroidRuntime (4997): java.lang.OutOfMemoryError: 位图大小超出执行者 VM 预算

也已经尝试过使用

image.setImageURI(null);
System.gc();  

在 onResume()、onPause()、onDestroy() 中,但没有任何效果。

还阅读了这篇文章:[链接][1]

if(!((BitmapDrawable)image.getDrawable()).getBitmap().isRecycled()){
                ((BitmapDrawable)image.getDrawable()).getBitmap().recycle();
            }
            Bitmap thumbnail = null;
            try {
                thumbnail = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(img));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             image.setImageBitmap(thumbnail); 

然后我收到以下错误:

12-12 15:28:42.879: E/AndroidRuntime(5296): java.lang.RuntimeException: Canvas: 试图使用回收的位图 android.graphics.Bitmap@40756520

除了当我的列表视图上下滚动时它不断崩溃,我相信它正在请求图像..

我不知道还能做什么,有什么建议吗?

编辑:

我发现另一个帖子在相同的解决方案中完美地解决了这个问题,但是我相信它需要一个图像缓存,因为当向上或向下滚动列表时她战斗的那个,这对用户体验非常不利.有什么想法可以解决吗?

以下代码:

在适配器中: ...

String imagePath = getPath(Uri.parse(img));
image.setImageBitmap(decodeSampledBitmapFromResource(imagePath, 85, 85));

...

方法:

public String getPath(Uri uri)  
    { 
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        return cursor.getString(idx);
    } 

    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 2;

    if (height > reqHeight || width > reqWidth) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    }
    return inSampleSize;

    }

    public static Bitmap decodeSampledBitmapFromResource(String resId,
            int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(resId, options);
    }

【问题讨论】:

  • 我不是从网络或远程服务器拍照,图像保存到设备本身,我检索先前保存在数据库中的路径

标签: android image bitmap uri


【解决方案1】:

听起来您想从本地图库中获取缩略图。 SDK直接提供了更好的解决方案:

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap thumbnail = Thumbnails.getThumbnail(context.getContentResolver(), /*ID of the local item*/, Thumbnails.MINI_KIND, options);
        // Calculate inSampleSize
        options.inSampleSize = UIUtils.calculateInSampleSize(options, reqWidth, reqHeight);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        thumbnail = Thumbnails.getThumbnail(context.getContentResolver(), /*ID of the local item*/, Thumbnails.MINI_KIND, options);

【讨论】:

  • 这一行 options.inSampleSize UIUtils.calculateInSampleSize = (options, 85, 85);引用了 UIUtils,但没有引用任何要导入的引用,也许是您自己设计的一些代码?
  • 我发现另一个帖子在相同的解决方案中完美地解决了这个问题,我将编辑帖子并放置代码,但是我相信他们需要缓存图像,因为当向上滚动列表或打倒了她,这对用户来说是非常糟糕的体验。有什么想法可以解决吗?
  • 当然,这篇文章解释了你所需要的一切here
猜你喜欢
  • 2011-10-22
  • 2013-05-16
  • 1970-01-01
  • 2014-06-21
  • 2023-04-09
  • 2011-02-25
相关资源
最近更新 更多