在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;
}
Run Code Online (Sandbox Code Playgroud)
我想我应该在某处使ImageView无效,但我无法让它正常工作.ImageLoader是一个(非常)简单的类,用于加载图像 - 来自LruCache,磁盘/ SD卡或远程获取它.
Luk*_*lor 15
您收到此错误是因为您无法访问回收的Bitmap.正如Android Developer网站所述:
释放与此位图关联的本机对象,并清除对像素数据的引用.这不会同步释放像素数据; 如果没有其他引用,它只是允许它被垃圾收集.位图标记为"死",这意味着如果调用getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容.此操作无法撤消,因此只有在您确定位图没有进一步用途时才应调用此操作.这是一个高级调用,通常不需要调用,因为正常的GC进程将在没有更多对此位图的引用时释放此内存.
我建议你不要回收Bitmap到目前为止,因为它仍然有用.因此,请在调用recycle()方法时查看代码,然后将其删除.
当点到位不再需要使用Bitmap时,我建议你使用这个方法来处理Bitmap:
public void disposeBitmap(Bitmap bitmap) {
bitmap.recycle();
bitmap = null;
}
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助.
事实证明,这个错误是由我的类oldBitmap.recycle()中的entryRemoved(..)方法调用覆盖LruCache引起的.由于位图可能仍然附加到ImageView调用recycle()将导致麻烦.
如果我理解正确:LruCache的缓存大小将在其构造函数中设置.当项目数超过此大小时,对象将有资格进行垃圾收集,这将在位图不再与ImageView关联时发生.
网上的很多示例和教程都表明recycle()应该调用它entryRemoved(..),但从我看到的情况来看,这是错误的.