在GridView中释放内存

时间:2013-08-05 15:56:31

标签: android memory gridview

对于我正在开发的应用,我正在尝试使用大量图像填充GridView。为了避免OutOfMemoryExceptions,我检查可用内存量,当达到某个阈值时,我尝试释放内存,如下所示:

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;
        }
    }
}

我注意到这实际上并没有释放内存。我不知道的是为什么。我错过了什么吗?

2 个答案:

答案 0 :(得分:3)

当您的ImageAdapter获取带有convertView not null的“getView()”回调时,它会告诉您以前由ImageAdapter提供的视图在屏幕上不再可见。这是恢复视图使用的资源的好时机。有点像:

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

应删除对ImageView中存储的Drawable的引用。如果您的代码中没有其他引用,那么它应该可用于垃圾收集。

更好的是,如果您要显示另一个图像。

iv.setDrawable(newImage);

然后返回convertView作为网格使用的新视图 将用新的Drawable替换旧的Drawable,删除引用并可能垃圾收集图像。

答案 1 :(得分:0)

您应该查看Android的BitmapFactory.Options类。它在Bitmap上提供了许多控件,在处理大量图像时它们非常有趣。

我认为最好的解决方案是将 inSampleSize 设置为2或4之类的值。这会降低图像的质量,但会节省大量内存。尝试不同的值,直到找到合适的比率。

来自Android doc(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 ,允许系统使用现有Bitmap中的空间,但必须小心,因为它可能导致崩溃或位图无效。