2012-08-28 74 views
1

我正在寫一個簡單的android應用程序,它使用ImageView來顯示圖像。當點擊一個按鈕時,它會根據當前圖像生成一個新的位圖,並替換舊的位圖。爲什麼這個圖像切換代碼有內存泄漏?

我用的圖片並不大:220 x 213

但在模擬器中,當我點擊按鈕的時候,它會拋出一個錯誤:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 

我讀過一些文章:

  1. java.lang.OutOfMemoryError: bitmap size exceeds VM budget - Android
  2. http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
  3. http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html

但仍不能解決我的問題。

我的代碼是:

public class MyActivity extends Activity { 
    private Bitmap image; 
    private ImageView imageView; 
    private Button button; 

    /** 
    * Called when the activity is first created. 
    */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     this.button = (Button) findViewById(R.id.button); 
     this.imageView = (ImageView) findViewById(R.id.image); 


     this.image = BitmapFactory.decodeResource(getResources(), R.drawable.m0); 
     this.imageView.setImageBitmap(image); 

     this.button.setOnClickListener(new View.OnClickListener() { 
      private int current = 0; 

      @Override 
      public void onClick(View view) { 
       Bitmap toRemove = image; 
       Matrix matrix = new Matrix(); 
       matrix.setRotate(30, 0.5f, 0.5f); 
       image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true); 
       imageView.setImageBitmap(image); 

       if (toRemove != null) { 
        toRemove.recycle(); 
       } 
      } 
     }); 
    } 
} 

你可以看到我已經移除圖像調用toRemove.recycle()。但似乎沒有效果。


UPDATE:

由於錯誤只發生時我按一下按鈕第五次(不是第一次),我們可以看到的圖像尺寸是沒有問題的。在我的代碼中,我試圖在生成新圖像後發佈舊圖像,所以我認爲舊圖像尚未正式發佈。

我已經調用toRemove.recycle(),這是釋放圖像的正確方法嗎?或者我會使用別的東西?


FINALLY:

埃米爾是正確的。我添加了一些代碼,記錄大小,你可以看到它每一次增加:

08-28 13:49:21.162: INFO/image size before(2238): 330 x 320 
08-28 13:49:21.232: INFO/image size after(2238): 446 x 442 
08-28 13:49:31.732: INFO/image size before(2238): 446 x 442 
08-28 13:49:31.832: INFO/image size after(2238): 607 x 606 
08-28 13:49:34.622: INFO/image size before(2238): 607 x 606 
08-28 13:49:34.772: INFO/image size after(2238): 829 x 828 
08-28 13:49:37.153: INFO/image size before(2238): 829 x 828 
08-28 13:49:37.393: INFO/image size after(2238): 1132 x 1132 
+1

登錄在你的onClick()方法的開始和結束的寬度和高度。查看圖片是否隨着每次點擊而改變大小。 – Emile

+0

有可能你在其他地方有內存泄漏,位圖恰好是用盡剩餘內存的對象。 – mbeckish

+0

@Emile,謝謝!你是對的!我會將日誌附加到問題 – Freewind

回答

2

我不知道Bitmap.createBitmap()很是如何工作的,但考慮到誤差做的「位圖大小'

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 

我會推測圖像的大小隨着每次點擊而增加。因此第5次點擊發生錯誤。

我會建議大小增加與旋轉矩陣有關。當圖像旋轉時,它看起來並不是將旋轉後的圖像裁剪爲圖像的寬度和高度,而是增加了圖像的大小。

你將不得不嘗試一些替代方法來處理你想要的w/h範圍內的旋轉。

這個問題的答案(兩下)顯示瞭如果你願意的話,如何裁剪旋轉的圖像。 Android: How to rotate a bitmap on a center point

RectF rectF = new RectF(0, 0, source.getWidth(), source.getHeight()); 
matrix.mapRect(rectF); 
+0

我跟着你提供的鏈接和代碼,但仍然沒有得到正確的結果。請幫助我解決這個問題:http://stackoverflow.com/questions/12163801/how-to-rotate-an-image-many-times-but-always-keep-the-4-corners-of-original-imag – Freewind