zoukankan      html  css  js  c++  java
  • 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





  • 相关阅读:
    C#接口入门学习
    消息队列接收时报错:对消息队列系统的访问被拒绝
    给某做测试的好友的建议
    在不同的Sql Server 数据库服务器(不同机器)导数据。
    如何让开发人员更好测试?
    存储过程初探
    语音报警.NET开发初探
    vs2010下Siverlight开发环境安装
    C# HttpWebRequest 从google服务器获取google的PageRank PR值
    创建进程API CreateProcess Demo
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7144151.html
Copyright © 2011-2022 走看看