IllegalArgumentException: Cannot draw recycled bitmaps

Android 码拜 9年前 (2015-08-12) 1220次浏览

代码如下:

Bitmap bm = BitmapFactory.decodeResource(res, id);

Bitmap newBm = Bitmap.createScaledBitmap(bm , 100,100, true);

bm.recyle();

mImageView.setImageBitmap(newBm);

报一个异常:

java.lang.IllegalArgumentException: Cannot draw recycled bitmaps

如果先mImageView.setImageBitmap(newBm); 再bm.recyle(); 还是一样报异常, 求解

#1
要先判断这个bitmap 是否回收过了。bm.recyle(); 你都回收了,就不能绘制在UI上面了。ImageView需要bitmap的数据内容
#2
我回收的是第一个bitmap  imageview里面用的是第二个bitmap 不是同一个呀
#3
他需要bitmap对象绘制到UI上,这个对象你回收了 就无法绘制了,其实是一个数据内存数据。你可以看源代码。

Bitmap

canvas.drawBitmap(source, srcR, dstR, paint);

#4

回复3楼:

 Bitmap bm = BitmapFactory.decodeResource(res, id);

Bitmap newBm = Bitmap.createScaledBitmap(bm , 100,100, true);

我回收的是bm 为何newBm也变成recyled了, 这两个bitmap不是同一个对象啊

#5
canvas.drawBitmap(source, srcR, dstR, paint); 这个source就是你传入的Bitmap对象,如果你回收了 系统就会报错。

#6

回复5楼:

这个我知道, 我想知道的是newBm我没有手动回收它, 为什么变成回收状态了

也就是说: Bitmap newBm = Bitmap.createScaledBitmap(bm , 100,100, true); 我把bm回收 为什么newBm也跟着回收了?

#7

50分

createScaledBitmap

Creates a new bitmap, scaled from an existing bitmap, when possible.

If the specified width and height are the same as the current width and height of the source btimap, the source bitmap is returned and now new bitmap is created.

#8
你可以New一个Canvas然后把Bm画上去再保存下,然后再回收Bm。

你上面的做法是把Bm当做参数传进去,然后,你又回收了这个Bm参数,所以系统给你报了非法参数的异常。

#9
代码没错,不过少了一句:

Bitmap bm = BitmapFactory.decodeResource(res, id);

 Bitmap newBm = Bitmap.createScaledBitmap(bm , 100,100, true);

 bm.recyle();

mImageView.setImageBitmap(null);//使用之前一定要先把ImageView清空,要不然会出现你所述的异常

 mImageView.setImageBitmap(newBm);

#14
如果尺寸相同,会直接返回原来的图片。

你需要检查newBmp和bm是不是同一个图片。

#16

回复14楼:

这个不是, 我打印了两个地址 不一样

#17

回复8楼:

难道Bitmap.createScaledBitmap(bm , 100,100, true)这个方法是异步的吗,不然已经执行完了我回收应该没问题呀

#18
应该是7楼说的

The new scaled bitmap or the source bitmap if no scaling is required.

楼主检查一下创建的和原图片的宽高是否一样,如果一样返回的就是原本的bitmap,不创建新的,bm和newBm引用的是一个bitmap.

#19

回复2楼:

你回收的其实是同一个对象!

你第二个Bitmap并不是new出来的,这里只是第一个Bitmap的引用。

所以第一个Bitmap回收后,第二个Bitmap指向的内存也被回收了。

至于你先setImageBitmap()再recycle(),则是因为setImageBitmap()调用时,并非立即重绘。而是先保存bitmap的引用,然后通知主线程去重绘,主线程收到消息后,再调用Bitmap引用重绘UI。

这时就会出现这个错误。

#20
给bm.recyle()这句加个判断,应该就不会报错了.

if(newBm !=bm ){

      bm.recyle();

}

#21

回复7楼:

正解,但是打错一个关键的单词

 and now new bitmap is created ——应该是—–>  and no new bitmap is created

 now——应该是—–>  no

表示不会创建bitmap, 而不是现在创建bitmap


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明IllegalArgumentException: Cannot draw recycled bitmaps
喜欢 (0)
[1034331897@qq.com]
分享 (0)