2013-08-05 68 views
0

對於我正在開發的應用程序,我試圖用很多圖像填充GridView。爲了避免OutOfMemoryExceptions,我檢查可用內存量,並在達到一定的閾值時,我嘗試以釋放內存,就像這樣:釋放GridView中的內存

private void freeUpMemory() { 
    // Clear ImageViews up to current position 
    for (int i = 0; i < mCurrentPosition; i++) { 
     RelativeLayout gridViewElement = (RelativeLayout) mGridView.getChildAt(i); 
     if (gridViewElement != null) { 
      ImageView imageView = (ImageView) gridViewElement.findViewById(R.id.image); 
      imageView.getDrawable().setCallback(null); 
      imageView = null; 
     } 
    } 
} 

我注意到,這實際上並沒有釋放內存。我不知道的是爲什麼。我錯過了什麼嗎?

+0

您是否創建了自己的ImageAdapter?它是否實現了GetView?如果是這樣,釋放視圖中的圖像傳遞給你作爲convertView將是最有效的方式來管理你的內存使用。 –

+0

將imageView設置爲null不起作用。你所做的只是清除你的本地參考。如果您在convertView上調用setDrawable,並且沒有其他引用,則應釋放內存。 –

+0

是的,我用我自己的ImageAdapter與getView()。 GridView中的每個元素都是一個包含ImageView和TextView的RelativeLayout。在ImageView上我使用setImageBitmap。我將如何釋放作爲convertView傳遞的圖像?這聽起來很有希望,你可以舉一個例子嗎? – Zero

回答

3

當ImageAdapter獲取「getView()」回調並且convertView不爲空時,它告訴您以前由ImageAdapter提供的此視圖在屏幕上不再可見。這是恢復視圖使用的資源的好時機。沿線的東西:

ImageView iv = (ImageView)convertView.findViewById(R.id.image_view_in_grid_item); 
iv.setDrawable(null); 

應該刪除存儲在ImageView中的Drawable的引用。如果代碼中沒有其他引用可用於Drawable,則應該可用於垃圾回收。

更好的是,如果你有另一個圖像顯示。

iv.setDrawable(newImage); 

然後返回convertView作爲新的視圖到由網格 可以使用將用一個新的代替舊的可繪製對象,移除所述參考和潛在垃圾收集圖像。

0

您應該看看Android的BitmapFactory.Options類。它在位圖上提供了許多控件,並且在處理大量圖像時兩個控件非常有趣。

我認爲最好的解決方案是將inSampleSize設置爲像2或4這樣的值。這會降低圖像質量,但會節省大量內存。嘗試不同的值,直到找到一個好的比例。從Android的文檔

樣品(http://developer.android.com/training/displaying-bitmaps/load-bitmap.html):

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

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

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

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

還有inPurgeable,使系統從現有的位圖使用的空間,但你一定要小心,因爲它可以導致崩潰或無效的位圖。

+0

我的問題不是如何減少圖像的內存使用量。我已經知道如何做到這一點。我想知道的是當OutOfMemoryException即將發生時如何釋放內存,因爲我可以在GridView中擁有基本無限的圖像。 – Zero

+0

您是否檢查過Drawable沒有其他參考? 也許Bitmap.recycle()可以提供幫助。 – noKid

+0

是的,我也嘗試過,但沒有幫助:/。顯然,這些位圖已經自動收集垃圾。 – Zero