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

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;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Android,常见错误)