2010-02-03 63 views
20

我有一个非常简单的应用程序,只有一个ImageView和一个按钮。我的ImageView加载的第一个Drawable资源是在XML Layout中的“android:src”标签中指定的,但是在运行时我想更改它显示的图片。要做到这一点,我开始一个活动的结果从SD卡中选择一个图像(意图发送到MediaStore.Images.Media.EXTERNAL_CONTENT_URI)。被选中的图片然而,当我尝试更新与所选择的图片的URI的ImageView的,但我得到的消息“java.lang.OutOfMemoryError:位图大小超过VM预算更改ImageView内容导致OutOfMemoryError

我'尝试加载拍摄的照片与我的HTC - 英雄的照相机(图片大小约为1.1M),但没有成功,似乎只适用于小于500KB的图片。但我需要加载使用相机拍摄的照片。 我该如何解决这个问题?我做错了什么。在我看来,代码非常简单,应该可以工作。

public void onClick(View v){ 
Intent selectImageIntent=new Intent(Intent.ACTION_PICK , 
    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
    startActivityForResult(selectImageIntent,1); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
super.onActivityResult(requestCode, resultCode, data); 
if(resultCode==Activity.RESULT_OK){ 
    Uri selectedImageUri = data.getData(); 
    Log.i(TAG,"chosen image: "+selectedImageUri.toString()); 
    ImageView imageView = (ImageView) this.findViewById(R.id.ImageView01); 
    imageView.setImageURI(selectedImageUri);//here I get the OutOfMemoryError 
    imageView.invalidate(); 

}else{ 
    //canceled 
} 

} 

p.s.这是应用程序应该做的唯一的事情,我不会创建其他对象,所以我想指出,除了显示图像外,我没有为其他内容使用堆空间。

回答

43

好像之前加载一个新的位图我不得不回收由ImageView显示的位图,现在它工作没有问题。希望这可以帮助别人,只需在设置新ImageView的内容之前调用folowing方法即可。

((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle();

,使代码现在看起来像这样:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
    super.onActivityResult(requestCode, resultCode, data); 
    switch(requestCode){ 
     case INTENT_REQUEST_SELECT_IMAGE: 
      if(resultCode==Activity.RESULT_OK){ 
       Uri selectedImageUri = data.getData(); 
       Log.i(TAG,"selectedImageUri.getPath()"+selectedImageUri.getPath()); 
       ImageView imageView = (ImageView) this.findViewById(R.id.ImageView_of_text); 
       ((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle(); 
       imageView.setImageURI(selectedImageUri); 
       imageView.invalidate(); 

      }else{ 
       //TODO define what to do in case the user canceled OCR or any other event 
      } 
      break; 
     default: 
      break; 
    } 
} 

请注意调用上的ImageView的位图回收。

2

现在问题已经解决。 而不是只有一条线:

((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle(); 

更新ImageView的内容前添加以下代码:

Drawable toRecycle= gallerypic.getDrawable(); 
if (toRecycle != null) { 
    ((BitmapDrawable)gallerypic.getDrawable()).getBitmap().recycle(); 
} 
gallerypic.setImageURI(selectedimage); 
6

这是我逼疯。

我正在为Xoom打造非常大,高分辨率的全屏图像(800x1232)。

下面的代码为我工作:

public void onStop() 
{ 
    super.onStop(); 
    imageView.setImageBitmap(null); 
} 

祝你好运!

+0

如果对ImageView使用FragmentStatePagerAdapter,则此方法将节省您的时间,因为回收位图时会重新膨胀视图时会导致错误。 – 2012-04-27 00:17:29

1

更新前仅使用此图像view: imageView1.setImageURI(null);

1

我用这个帖子的每一个解决方案和更多,但没有人工作。最后我在清单中使用android:largeHeap="true" ,并解决了我的问题。

希望这可以帮助别人。