对于我正在开发的应用,我正在尝试使用大量图像填充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;
}
}
}
我注意到这实际上并没有释放内存。我不知道的是为什么。我错过了什么吗?
答案 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中的空间,但必须小心,因为它可能导致崩溃或位图无效。