循环里调用Bitmap.recycle(),出现异常:trying to use a recycled bitmap。

A295623449 2011-08-02 04:38:27


//出错的函数是这样的

Bitmap btSrc = Bitmap.createBitmap(....);
Matrix mx = new Matrix();
int clipX = .. , clipY = .. ,clipW = ..,clipH = ..;

for(int i=0;i<5;i++){

Bitmap btMid = Bitmap.createBitmap(btSrc, 0, 0, btSrc.getWidth(), btSrc.getHeight(), mx, true);
Bitmap btClip = Bitmap.createBitmap(btMid, clipX,clipY,clipW,clipH);

if(btMid!=null&&!btMid.isRecycled()){
btMid.recycle(); //释放图片占用的堆栈内存。
btMid = null;
}
if(btClip!=null&&!btClip.isRecycled()){
btClip.recycle();
btClip = null;
}

}





在i = 2 时,发生Canvas: trying to use a recycled bitmap错误。
btMid 和 btClip 是局部变量,每次用完后就recycle()了,下个循环里又是新的,怎么会使用同一个变量内存呢??
...全文
2174 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
java5506113 2012-05-24
  • 打赏
  • 举报
回复
学习了,mark 一下 以后会用到
卷毛大帝 2012-02-15
  • 打赏
  • 举报
回复
楼主我也遇到你这个问题了,和你的基本一模一样,你最后怎么解决的?
[Quote=引用 10 楼 fontlose 的回复:]

引用 8 楼 a295623449 的回复:
引用 6 楼 fontlose 的回复:

引用 5 楼 a295623449 的回复:
引用 4 楼 fontlose 的回复:
// check if we can just return our argument unchanged
if (!source.isMutable() &amp;amp;amp;amp;&……
[/Quote]
zac35 2011-12-24
  • 打赏
  • 举报
回复
楼主最后怎么解决的啊?
我也遇到了这个问题,如果在缩放之前释放还是会报java.lang.OutOfMemoryError: bitmap size exceeds VM budget异常。
佐助 2011-12-09
  • 打赏
  • 举报
回复
学习了,试一下可不可以,谢谢
A295623449 2011-08-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 claire1989 的回复:]

是不是Bitmap.createBitmap 不用回收了???
[/Quote]

你看看createBitmap的原函数,参数中某个或某几个不变(排列组合),再看创建出的bitmap的hashcode是否一样就知道了。
yzayqc 2011-08-25
  • 打赏
  • 举报
回复
是不是Bitmap.createBitmap 不用回收了???
fontlose 2011-08-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 a295623449 的回复:]
引用 6 楼 fontlose 的回复:

引用 5 楼 a295623449 的回复:
引用 4 楼 fontlose 的回复:
// check if we can just return our argument unchanged
if (!source.isMutable() &amp;amp;amp;&amp;amp;amp; x == 0 &amp;……
[/Quote]
是的 只要改下createBitmap的几个参数来保证不会返回原来的对象。
A295623449 2011-08-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fontlose 的回复:]

引用 5 楼 a295623449 的回复:
引用 4 楼 fontlose 的回复:
// check if we can just return our argument unchanged
if (!source.isMutable() &amp;amp;&amp;amp; x == 0 &amp;amp;&amp;amp; y == 0 &a……
[/Quote]

我刚试了,btMid、btClip和btSrc的hashCode是相同的。
A295623449 2011-08-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fontlose 的回复:]

引用 5 楼 a295623449 的回复:
引用 4 楼 fontlose 的回复:
// check if we can just return our argument unchanged
if (!source.isMutable() &amp;amp;&amp;amp; x == 0 &amp;amp;&amp;amp; y == 0 &a……
[/Quote]

哦,明白了。
那意思就是btMid和btClip和btSrc相同都是某一对象的引用,
Bitmap.createBitmap只是创建了两个引用而已,对吗?
jaylijianbin 2011-08-02
  • 打赏
  • 举报
回复
gfdhhgfhgfh
fontlose 2011-08-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 a295623449 的回复:]
引用 4 楼 fontlose 的回复:
// check if we can just return our argument unchanged
if (!source.isMutable() &amp;&amp; x == 0 &amp;&amp; y == 0 &amp;&amp; width == source.getWidth() &……
[/Quote]
这个是数学问题 矩阵有恒等矩阵,你前面new的Matrix就是恒等矩阵,满足上面这个条件会把传进的对象直接返回。而你又把这个对象给recycle了



A295623449 2011-08-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fontlose 的回复:]
// check if we can just return our argument unchanged
if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
height == source.getHeight() &&……
[/Quote]

这个m.identify()的涵义是不是上一个matrix和这一个matrix是同一对象?
fontlose 2011-08-02
  • 打赏
  • 举报
回复

// check if we can just return our argument unchanged
if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
height == source.getHeight() && (m == null || m.isIdentity())) {
return source;
}



Bitmap btMid = Bitmap.createBitmap(btSrc, 0, 0, btSrc.getWidth(), btSrc.getHeight(), mx, true);


btMid 会返回btSrc对象 你把btMid recycle了实际就是把btSrc给回收了 下次用当然报错了
你可以Debug下这两个的ID
fontlose 2011-08-02
  • 打赏
  • 举报
回复
看源码

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
Matrix m, boolean filter) {

checkXYSign(x, y);
checkWidthHeight(width, height);
if (x + width > source.getWidth()) {
throw new IllegalArgumentException("x + width must be <= bitmap.width()");
}
if (y + height > source.getHeight()) {
throw new IllegalArgumentException("y + height must be <= bitmap.height()");
}

// check if we can just return our argument unchanged
if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
height == source.getHeight() && (m == null || m.isIdentity())) {
return source;
}

int neww = width;
int newh = height;
Canvas canvas = new Canvas();
Bitmap bitmap;
Paint paint;

Rect srcR = new Rect(x, y, x + width, y + height);
RectF dstR = new RectF(0, 0, width, height);

if (m == null || m.isIdentity()) {
bitmap = createBitmap(neww, newh,
source.hasAlpha() ? Config.ARGB_8888 : Config.RGB_565);
paint = null; // not needed
} else {
/* the dst should have alpha if the src does, or if our matrix
doesn't preserve rectness
*/
boolean hasAlpha = source.hasAlpha() || !m.rectStaysRect();
RectF deviceR = new RectF();
m.mapRect(deviceR, dstR);
neww = Math.round(deviceR.width());
newh = Math.round(deviceR.height());
bitmap = createBitmap(neww, newh, hasAlpha ? Config.ARGB_8888 : Config.RGB_565);
if (hasAlpha) {
bitmap.eraseColor(0);
}
canvas.translate(-deviceR.left, -deviceR.top);
canvas.concat(m);
paint = new Paint();
paint.setFilterBitmap(filter);
if (!m.rectStaysRect()) {
paint.setAntiAlias(true);
}
}

// The new bitmap was created from a known bitmap source so assume that
// they use the same density
bitmap.mDensity = source.mDensity;

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

return bitmap;
}

/**
* Returns a mutable bitmap with the specified width and height. Its
* initial density is as per {@link #getDensity}.
*
* @param width The width of the bitmap
* @param height The height of the bitmap
* @param config The bitmap config to create.
* @throws IllegalArgumentException if the width or height are <= 0
*/
public static Bitmap createBitmap(int width, int height, Config config) {
Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);
bm.eraseColor(0); // start with black/transparent pixels
return bm;
}
A295623449 2011-08-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dinjay 的回复:]

....杯具吧,recycle只是给系统发个消息,通知系统回头可以回收这个位图占用的内存了,不代表你调用完recycle系统就马上给free掉,recycle只是一个通知而已。
[/Quote]

但是,系统回不回收和新生成的对象又有什么关系呢?
dinjay 2011-08-02
  • 打赏
  • 举报
回复
....杯具吧,recycle只是给系统发个消息,通知系统回头可以回收这个位图占用的内存了,不代表你调用完recycle系统就马上给free掉,recycle只是一个通知而已。

80,354

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧