您的位置:首页 > 移动开发 > Android开发

Bitmap回收—Canvas: trying to use a recycled bitmap android.graphics

2017-06-03 11:22 387 查看
bitmap 回收时

/**

 * onDestroy方法

 * */

@Override

protected void onDestroy() {
super.onDestroy();
BitmapToBase.recycleBitmap(bitmap);

}

/**

 * 回收bitmap

* */

public static void recycleBitmap(Bitmap bitmap){
if(bitmap!=null){
if(!bitmap.isRecycled()){ 
bitmap.recycle();  

}

}

偶尔报错 错误如下

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@f08cd43
at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1270)
at android.graphics.Canvas.drawBitmap(Canvas.java:1404)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:544)
at android.widget.ImageView.onDraw(ImageView.java:1244)
at android.view.View.draw(View.java:16669)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.draw(View.java:16681)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.draw(View.java:16681)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.draw(View.java:16681)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.draw(View.java:16681)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.widget.ListView.drawChild(ListView.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.widget.AbsListView.dispatchDraw(AbsListView.java:2800)
at android.widget.ListView.dispatchDraw(ListView.java:3604)
at android.view.View.draw(View.java:16681)
at android.widget.AbsListView.draw(AbsListView.java:4749)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.draw(View.java:16681)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.draw(View.java:16681)
at android.widget.ScrollView.draw(ScrollView.java:1900)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.draw(View.java:16681)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchDraw(PhoneWindow.java:2794)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at android.view.View.updateDisplayListIfDirty(View.java:15614)
at android.view.View.draw(View.java:16423)
at android.view.ViewGroup.drawChild(ViewGroup.java:3735)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3525)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchDraw(PhoneWindow.java:2794)
at android.view.View.draw(View.java:16681)
at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.java:2780)
at android.view.View.updateDisplayListIfDirty(View.java:15622)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:286)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:292)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:327)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3088)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2892)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2504)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1335)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6869)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:894)
at android.view.Choreographer.doCallbacks(Choreographer.java:696)
at android.view.Choreographer.doFrame(Choreographer.java:631)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:880)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5917)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)

用处

imageview.setDrawingCacheEnabled(true);

bitmap=Bitmap.createBitmap(imageview.getDrawingCache());

imageview.setDrawingCacheEnabled(false);

即 在imagview 上显示图片 点击按钮 保存imageview上的图片 

解决方法

自定义Imageview 重写ondraw方法 再次捕获异常

/**

* onDraw 方法 捕获异常(图片回收时)

 * */

@Override

protected void onDraw(Canvas canvas) {
try{
super.onDraw(canvas);
}catch (Exception e){
System.out.println("ImageView->onDraw() Canvas: trying to use a recycled bitmap");
}

}

还看到其他用法的解决方法

Bitmap bitmap = Bitmap.createBitmap(temp, 0, 0, width, height, matrix,true);方法了。

把temp.recycle();后就报了那个错误。

 

原因是传入的temp图片和新的bitmap图片分辨率一样。createBitmap的源码就会直接返回temp对象,而不是新建一个bitmap对象,这样temp.recycle()被回收后,bitmap自然也被回收了。

解决方法把传入图片换个分辨率。

或者使 width, height, 和生成matrix的width, height不一样,就行了

 

if(newHeight==height&&newWidth==width){

//强制使新旧图片分辨率不一样,防止temp和bitmap是同一对象

height=height-1;

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐