2010-02-03 58 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" ,並解決了我的問題。

希望這可以幫助別人。