2012-03-10 40 views
0

我用下面的函数来获取在Android上联系人的照片,而该人的查找关键字给出:的OutOfMemoryError在Android中显示联系人的照片时(位图大小超过VM预算)

public Bitmap getContactPhoto(String lookup_key) { 
    Uri lookUpUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup_key); 
    Uri contentUri = ContactsContract.Contacts.lookupContact(ctx.getContentResolver(), lookUpUri); 
    InputStream stream = null; 
    try { 
     stream = ContactsContract.Contacts.openContactPhotoInputStream(ctx.getContentResolver(), contentUri); 
    } 
    catch (Exception e) { 
    } 
    if (stream != null) { 
     return BitmapFactory.decodeStream(stream, null, bitmapOptions); 
    } 
    else { 
     return null; 
    } 
} 

当我显示这些接触在列表视图中的照片,我有时读在开发者控制台的崩溃报告以下错误:

Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=6023KB, Allocated=3002KB, Bitmap Size=27152KB) 

这是否意味着我的应用程序可以使用大约堆3MB而是一个位图有大约27MB?

我读了很多关于内存不足错误的问题在这里对堆栈溢出,但它主要是关于:

  • 泄漏环境,使垃圾收集器不能释放的资源
  • 需要扩大规模巨大的位图

但是我怎样才能防止我的错误呢?由于我只能获取联系人的照片,因此我不知道是否有必须缩放的巨大位图。在这种情况下,泄漏情况似乎并非如此。

这是怎样的图像显示:

imageView.setVisibility(View.VISIBLE); 
imageView.setBackgroundResource(R.drawable.background); 
if (<BITMAP_OBJECT> != null) { 
    imageView.setImageBitmap(<BITMAP_OBJECT>); 
} 
else { 
    imageView.setImageBitmap(null); 
} 
+0

该问题与您展示的内容无关。请附上getContactPhoto()调用的代码 – Blackbelt 2012-03-10 18:55:33

+0

对不起,我现在添加了这个。 – caw 2012-03-10 19:16:38

+0

你打电话给你发布在某种适配器上的最后一个片段吗 – Blackbelt 2012-03-10 19:56:04

回答

2

当你设置你的BitmapImageView,试试这样做:

Bitmap oldBitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); 
imageView.setImageDrawable(null); 
oldBitmap.recycle(); 
imageView.setImageBitmap(newBitmap); 

它可能不是完全摆脱问题,但它肯定会让它发生得更少。

+0

谢谢!当我试图实现这个时,imageView.getDrawable()的结果没有方法getBitmap()。另外,在我的情况下,是不是一个位图太大的错误? – caw 2012-03-10 19:13:07

+0

您必须将其转换为“BitmapDrawable”。如果你将'Bitmap'设置为这些'ImageView',那么这是一个安全的转换。 此外,底层问题可能只是内存不足。有时候这些错误是欺骗性的。值得一试的方式,这是一个很好的做法。 – 2012-03-11 07:33:05

+0

谢谢,现在它工作!不幸的是,我得到以下运行时异常:“画布:试图使用回收的位图。”因此,回收适配器条目/行似乎不是解决方案。 – caw 2012-03-12 22:19:47

0

你试过缩放位图吗?这里是你如何做到这一点...

BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(filename, options); 
     options.inJustDecodeBounds = false; 
     options.inSampleSize = 2; // adjust sample size to whatever you want it to be 

     bitmap = BitmapFactory.decodeFile(filename, options); 
     if (bitmap != null && exact) { 
      bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); 
     } 
的方法 BitmapFactory.decodeFile

在这里,我创建了一个缩放Bitmap因此它消耗较少的内存比以前,它解决了我的问题,你的呢?

相关问题