在Android 4.1中,对我来说,我们的应用程序中出现了看似奇怪的错误。在应用程序中,扩展BaseAdapter的自定义适配器附加到Gallery小部件。当从左到右快速滚动时,反之亦然,我得到一个带有异常消息的FC:
java.lang.IllegalArgumentException:无法绘制循环位图
getView(..)方法的代码如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null){
// View is not recycled. Inflate the layout.
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.gallery_image, parent, false);
viewHolder = new ViewHolder();
viewHolder.image = (ImageView) convertView.findViewById(R.id.gallery_image);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
viewHolder.image.setImageDrawable(null);
}
imageLoader.displayImage(images.get(position).getFilename(),
images.get(position).getUrlThumbnail(),
viewHolder.image,
Math.round(BitmapUtil.convertDpToPixel(400f, context)),
Math.round(BitmapUtil.convertDpToPixel(400f, context)));
return convertView;
}
我想我应该在某处使ImageView无效,但我无法让它正常工作。 ImageLoader是一个(非常)简单的类,用于加载图像 - 来自LruCache,磁盘/ SD卡或远程获取它。
答案 0 :(得分:15)
您收到此错误是因为您无法访问回收的Bitmap。正如Android开发者网站所述:
释放与此位图关联的本机对象,然后清除 参考像素数据。这不会释放像素数据 同步;它只是允许它被垃圾收集,如果有的话 没有其他参考。位图标记为“死”,意思是它 如果调用getPixels()或setPixels(),则会抛出异常 什么都不会。这个操作无法逆转,所以应该如此 只有在你确定没有进一步的用途时才被调用 位图。这是一个高级调用,通常不需要调用, 因为正常的GC过程会在没有时释放这个内存 更多对此位图的引用。
我建议你不要回收Bitmap到目前为止,因为它仍然有用。因此,请在调用recycle()
方法时查看代码,然后将其删除。
当点到了不再需要使用Bitmap的地方时,我建议你使用这个方法来处理Bitmap:
public void disposeBitmap(Bitmap bitmap) {
bitmap.recycle();
bitmap = null;
}
我希望这会有所帮助。
答案 1 :(得分:8)
事实证明,这个错误是由我的班级oldBitmap.recycle()
方法中的entryRemoved(..)
调用覆盖LruCache引起的。由于位图可能仍附加到ImageView,因此调用recycle()
会导致麻烦。
如果我理解正确:LruCache的缓存大小将在其构造函数中设置。当项目数超过此大小时,对象将有资格进行垃圾收集,这将在位图不再与ImageView关联时发生。
网上有很多示例和教程建议recycle()
应调用entryRemoved(..)
,但从我看到的情况来看,这是错误的。