Canvas is trying to use a recycled raster file

Since I updated my SDK / ADT to the latest changes with Android 4.4, and I'm not sure if this is related to this, but this is the only serious change that this error started with, I got this error in my application.

The log does not say where this is happening in my application. Although there are links to DrawerLayout . It also seems to be referencing the v4 support library, but I am using v13.

  11-16 15:45:12.406: E/AndroidRuntime(1236): FATAL EXCEPTION: main 11-16 15:45:12.406: E/AndroidRuntime(1236): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41f1e4e8 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1058) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.graphics.Canvas.drawBitmap(Canvas.java:1097) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13854) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.support.v4.widget.DrawerLayout.drawChild(DrawerLayout.java:804) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13823) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13823) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13823) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13947) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.widget.FrameLayout.draw(FrameLayout.java:467) 11-16 15:45:12.406: E/AndroidRuntime(1236): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2224) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2482) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2395) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2239) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1872) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer.doCallbacks(Choreographer.java:562) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer.doFrame(Choreographer.java:532) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.os.Handler.handleCallback(Handler.java:730) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.os.Handler.dispatchMessage(Handler.java:92) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.os.Looper.loop(Looper.java:137) 11-16 15:45:12.406: E/AndroidRuntime(1236): at android.app.ActivityThread.main(ActivityThread.java:5103) 11-16 15:45:12.406: E/AndroidRuntime(1236): at java.lang.reflect.Method.invokeNative(Native Method) 11-16 15:45:12.406: E/AndroidRuntime(1236): at java.lang.reflect.Method.invoke(Method.java:525) 11-16 15:45:12.406: E/AndroidRuntime(1236): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 11-16 15:45:12.406: E/AndroidRuntime(1236): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 11-16 15:45:12.406: E/AndroidRuntime(1236): at dalvik.system.NativeStart.main(Native Method) 

Here is just one code that I use BitMap in AsyncTask; this refers to the image that is in my listView header:

  static class GetProfileImageURL extends AsyncTask<String, String, Void> { private Bitmap b; private Context mContext; public GetProfileImageURL(Context c) { mContext = c; } @Override protected Void doInBackground(String... params) { URL url; try { String profImage = String.valueOf(Rateit.userId); url = new URL(Rateit.PROFILE_PIC_URL + profImage + ".jpg"); b = BitmapFactory.decodeStream(url.openConnection() .getInputStream()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } protected void onPostExecute(Void v) { if (mContext != null) { if (b != null) { userIcon.setImageBitmap(ImageHelper.getRoundedCornerBitmap( b, 50)); } } } } 

This AsyncTask is only called when an Activity is created.

As requested, ImageHelper Class:

 public class ImageHelper { public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap .getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; final Rect topRightRect = new Rect(bitmap.getWidth()/2, 0, bitmap.getWidth(), bitmap.getHeight()/2); final Rect bottomRect = new Rect(0, bitmap.getHeight()/2, bitmap.getWidth(), bitmap.getHeight()); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); // Fill in upper right corner canvas.drawRect(topRightRect, paint); // Fill in bottom corners canvas.drawRect(bottomRect, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; 
+6
source share
3 answers

As far as I understand correctly, this problem occurs only when the android tries to display the view for which the bitmap object is set, and during rendering, if the android detects that the bitmap object that was installed earlier was processed only then this exception. (Bitmap received processing for some strange or familiar reason after updating api !!!)

(Given that you did not call bitmap.recycle () anywhere)
The way I would try to fix it:

First try:

  • Let doInBackground return a Bitmap object.
  • Remove local variable (private Bitmap b;) from static AsyncTask
  • Configure onPostExecute accordingly:

     protected void onPostExecute(Bitmap bmp) { if (mContext != null) { if (bmp != null) { userIcon.setImageBitmap(ImageHelper.getRoundedCornerBitmap( bmp, 50)); } } } 

Second attempt:

  protected void onPostExecute(Void v) { if (mContext != null) { if (b != null) { Bitmap roundedbmp = ImageHelper.getRoundedCornerBitmap( b, 50); } } } 

Check only this to make sure that the problem with processing bitmap images did not arise from ImageHelper.getRoundedCornerBitmap (b, 50) of this code.

  protected void onPostExecute(Void v) { if (mContext != null) { if (b != null) { Bitmap roundedbmp = ImageHelper.getRoundedCornerBitmap( b, 50); if(roundedbmp!=null){ userIcon.setImageBitmap(roundedbmp); } } } } 

The solution I tried to come up with is purely based on the assumption and my past experience, so don't get me wrong. As you can see, the second solution does not make sense, but may or may not have anything to do with the presentation !!!. On the other hand, the first solution makes sense to me in terms of referencing a Bitmap object. Since I can understand that somewhere along the road during processing the raster image the object receives recirculation, based on this fact I tried to make two approaches. Hope this helps you.

+3
source

I will make a wild guess ...

In OnCreate, you refer to the components of the box layout so that the mgr layout. the cheater does not know about the asynchronous delay inherent in your task, so it goes ahead, not knowing that the async task has not yet been completed.

The problem may be that your view built in onCreate () should be able to put something together before the task is completed. When the task is completed, it needs to change the state of the View resources and report that some view component should be updated. For example, a dummy bit in resources, which stands for a rounded bitmap, will soon emerge from an asynchronous network search.

I do not know why you would not have the same problem on <4.4.

I assume that your problem is NOT related to orientation changes.

It is possible that this code may further clarify some delay issues due to asnyc. Perhaps this is irrelevant.

+1
source

check if you use bitmap_image.recycle () anywhere? Then comment on this and see if it works. I ran into a similar problem and fixed it.

0
source

Source: https://habr.com/ru/post/958219/


All Articles