Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap #24

Closed
rockerhieu opened this issue Apr 11, 2013 · 4 comments

Comments

@rockerhieu
Copy link

0   
java.lang.RuntimeException: An error occured while executing doInBackground()
1   
at android.os.AsyncTask$3.done(AsyncTask.java:299)
2   
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
3   
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
4   
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
5   
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
6   
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
7   
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
8   
at java.lang.Thread.run(Thread.java:856)
9   
Caused by: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41e89060
10  
at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)
11  
at android.graphics.Canvas.drawBitmap(Canvas.java:1096)
12  
at android.graphics.Bitmap.createBitmap(Bitmap.java:617)
13  
at android.graphics.Bitmap.createBitmap(Bitmap.java:514)
14  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.scaleBitmap(GPUImage.java:592)
15  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.loadResizedImage(GPUImage.java:574)
16  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:540)
17  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:516)
18  
at android.os.AsyncTask$2.call(AsyncTask.java:287)
19  
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
20  
... 4 more
21  
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41e89060
22  
at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)
23  
at android.graphics.Canvas.drawBitmap(Canvas.java:1096)
24  
at android.graphics.Bitmap.createBitmap(Bitmap.java:617)
25  
at android.graphics.Bitmap.createBitmap(Bitmap.java:514)
26  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.scaleBitmap(GPUImage.java:592)
27  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.loadResizedImage(GPUImage.java:574)
28  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:540)
29  
at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:516)
30  
at android.os.AsyncTask$2.call(AsyncTask.java:287)
31  
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
32  
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
33  
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
34  
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
35  
at java.lang.Thread.run(Thread.java:856)

From the SDK documentation http://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean):

Creates a new bitmap, scaled from an existing bitmap, when possible. If the specified width and height are the same as the current width and height of the source btimap, the source bitmap is returned and now new bitmap is created.

I think this error will be happen when the specified width and height are the same as the current width and height of the source bitmap.

private Bitmap scaleBitmap(Bitmap bitmap) {
            // resize to desired dimensions
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int[] newSize = getScaleSize(width, height);
            Bitmap workBitmap = Bitmap.createScaledBitmap(bitmap, newSize[0], newSize[1], true);
            bitmap.recycle();
            bitmap = workBitmap;
            System.gc();

            if (mScaleType == ScaleType.CENTER_CROP) {
                // Crop it
                int diffWidth = newSize[0] - mOutputWidth;
                int diffHeight = newSize[1] - mOutputHeight;
                workBitmap = Bitmap.createBitmap(bitmap, diffWidth / 2, diffHeight / 2,
                        newSize[0] - diffWidth, newSize[1] - diffHeight);
                bitmap.recycle();
                bitmap = workBitmap;
            }

            return bitmap;
        }

Should become this:

private Bitmap scaleBitmap(Bitmap bitmap) {
            // resize to desired dimensions
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int[] newSize = getScaleSize(width, height);
            Bitmap workBitmap = Bitmap.createScaledBitmap(bitmap, newSize[0],
                    newSize[1], true);
            if (workBitmap != bitmap) {
                bitmap.recycle();
                bitmap = workBitmap;
            }
            System.gc();

            if (mScaleType == ScaleType.CENTER_CROP) {
                // Crop it
                int diffWidth = newSize[0] - mOutputWidth;
                int diffHeight = newSize[1] - mOutputHeight;
                workBitmap = Bitmap.createBitmap(bitmap, diffWidth / 2,
                        diffHeight / 2, newSize[0] - diffWidth, newSize[1]
                                - diffHeight);
                if (workBitmap != bitmap) {
                    bitmap.recycle();
                    bitmap = workBitmap;
                }
            }

            return bitmap;
        }
@pboos
Copy link
Collaborator

pboos commented Apr 16, 2013

Thank you for your report. This really is a bug in the code. Will fix it.

@rockerhieu
Copy link
Author

Do you think we should search and check all Bitmap#recycle() in the source code and apply the same fix? There maybe other potential crashes.

@pboos
Copy link
Collaborator

pboos commented May 7, 2013

i checked other places where recycle is used. Those seemed okay.

mediavrog pushed a commit to mediavrog/android-gpuimage that referenced this issue Aug 1, 2013
@sharmapoonam
Copy link

I face this type of crash in my app please suggest me:

at android.widget.ListView.layoutChildren (ListView.java:1618)

at android.widget.AbsListView$CheckForTap.run (AbsListView.java:3457)

at android.os.Handler.handleCallback (Handler.java:751)

at android.os.Handler.dispatchMessage (Handler.java:95)

at android.os.Looper.loop (Looper.java:154)

at android.app.ActivityThread.main (ActivityThread.java:6195)

at java.lang.reflect.Method.invoke (Native Method)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:874)

at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:764)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants