Canvas: trying to use a recycled bitmap android.graphics.Bitmap@XXX

最近在做和图片相关显示的出现了一个问题,整理一下思路,分享出来给大家参考一下:

Exception Type:java.lang.RuntimeException
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@XXXXX 	at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1282)
	at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:599)
	at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:538)
	at android.widget.ImageView.onDraw(ImageView.java:1176)
	at android.view.View.draw(View.java:15285)
	at android.view.View.updateDisplayListIfDirty(View.java:14208)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.View.draw(View.java:15013)
	at android.view.ViewGroup.drawChild(ViewGroup.java:3409)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3202)
	at android.view.View.draw(View.java:15288)
	at android.widget.FrameLayout.draw(FrameLayout.java:598)
	at android.view.View.updateDisplayListIfDirty(View.java:14208)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.View.draw(View.java:15013)
	at android.view.ViewGroup.drawChild(ViewGroup.java:3409)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3202)
	at android.view.View.updateDisplayListIfDirty(View.java:14203)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.View.draw(View.java:15013)
	at android.view.ViewGroup.drawChild(ViewGroup.java:3409)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3202)
	at android.view.View.updateDisplayListIfDirty(View.java:14203)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.View.draw(View.java:15013)
	at android.view.ViewGroup.drawChild(ViewGroup.java:3409)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3202)
	at android.view.View.updateDisplayListIfDirty(View.java:14203)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.View.draw(View.java:15013)
	at android.view.ViewGroup.drawChild(ViewGroup.java:3409)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3202)
	at android.view.View.updateDisplayListIfDirty(View.java:14203)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.View.draw(View.java:15013)
	at android.view.ViewGroup.drawChild(ViewGroup.java:3409)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3202)
	at android.view.View.updateDisplayListIfDirty(View.java:14203)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.View.draw(View.java:15013)
	at android.view.ViewGroup.drawChild(ViewGroup.java:3409)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3202)
	at android.view.View.draw(View.java:15288)
	at android.widget.FrameLayout.draw(FrameLayout.java:598)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2799)
	at android.view.View.updateDisplayListIfDirty(View.java:14208)
	at android.view.View.getDisplayList(View.java:14230)
	at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:273)
	at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:279)
	at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:318)
	at android.view.ViewRootImpl.draw(ViewRootImpl.java:2552)
	at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2368)
	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1998)
	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1077)
	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5966)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:786)
	at android.view.Choreographer.doCallbacks(Choreographer.java:599)
	at android.view.Choreographer.doFrame(Choreographer.java:569)
	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:772)
	at android.os.Handler.handleCallback(Handler.java:743)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:135)
	at android.app.ActivityThread.main(ActivityThread.java:5299)
	at java.lang.reflect.Method.invoke(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:372)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

主要的跟踪方向

at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:599)
	at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:538)
	at android.widget.ImageView.onDraw(ImageView.java:1176)
在这ImageView和BitmapDrawable、GLES20Canvas三个类报出异常信息,在找到ImageView代码中,发现了OnDraw的方法的mDrawable.draw(canvas);这一句出现了错

有接着在BitmapDrawable的OnDraw方法发现了错误行canvas.drawBitmap(bitmap, null, mDstRect, paint);:


又对应在找到GLES20Canvas.java:599的问题:


马上找到了问题所在:

 protected static void throwIfCannotDraw(Bitmap bitmap) {
        if (bitmap.isRecycled()) {
            throw new RuntimeException("Canvas: trying to use a recycled bitmap " + bitmap);
        }
        if (!bitmap.isPremultiplied() && bitmap.getConfig() == Bitmap.Config.ARGB_8888 &&
                bitmap.hasAlpha()) {
            throw new RuntimeException("Canvas: trying to use a non-premultiplied bitmap "
                    + bitmap);
        }
    }
因此:可以说明:如果bitmap对象已经被回收了,但是BitmapDrawable的对象还在Canvas上绘制导致了跑出了该异常情况。

解决方案:

1、可以写一个集成ImageView的子类,单后复写onDraw()方法捕获此异常:

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		try{
			super.onDraw(canvas);
		}catch(Exception e){
		}
	}
2、在使用BitmapDrawable对象的时候可以,进行先将传递的bitmap对象判断,并在显示图片之前不要进行回收,直到使用完在回收。这种不建议,因为图片多会出现OOM





  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值