1

I am having trouble with an image that is being drawn that is too big and its killing my app.

The following error occurs:

java.lang.RuntimeException: Canvas: trying to draw too large (numbernumbernumberbytes) bitmap.

I have went through my app and I have disabled all large images that were loaded directly. Images that are loaded with Glide (Image loading library, https://github.com/bumptech/glide) should not be a problem.

The error still occurs and I was wondering if there was a way to trace the error. To see exactly which image is causing the problem.

Is there a way to trace this?

EDIT1:

The complete stacktrace of the error:

07-07 19:22:21.468 D/AndroidRuntime: Shutting down VM


                                     --------- beginning of crash
07-07 19:22:21.469 E/AndroidRuntime: FATAL EXCEPTION: main
                                     Process: com.linkhubapp, PID: 20097
                                     java.lang.RuntimeException: Canvas: trying to draw too large(132710400bytes) bitmap.
                                         at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)
                                         at android.graphics.Canvas.drawBitmap(Canvas.java:1420)
                                         at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545)
                                         at android.widget.ImageView.onDraw(ImageView.java:1286)
                                         at android.view.View.draw(View.java:18318)
                                         at android.view.View.updateDisplayListIfDirty(View.java:17296)
                                         at android.view.View.draw(View.java:18080)
                                         at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
                                         at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
                                         at android.view.View.updateDisplayListIfDirty(View.java:17291)
                                         at android.view.View.draw(View.java:18080)
                                         at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
                                         at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
                                         at android.view.View.updateDisplayListIfDirty(View.java:17291)
                                         at android.view.View.draw(View.java:18080)
                                         at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
                                         at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
                                         at android.view.View.updateDisplayListIfDirty(View.java:17291)
                                         at android.view.View.draw(View.java:18080)
                                         at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
                                         at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
                                         at android.view.View.updateDisplayListIfDirty(View.java:17291)
                                         at android.view.View.draw(View.java:18080)
                                         at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
                                         at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
                                         at android.view.View.draw(View.java:18321)
                                         at com.android.internal.policy.DecorView.draw(DecorView.java:919)
                                         at android.view.View.updateDisplayListIfDirty(View.java:17296)
                                         at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:692)
                                         at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:698)
                                         at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:806)
                                         at android.view.ViewRootImpl.draw(ViewRootImpl.java:3121)
                                         at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2917)
                                         at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2509)
                                         at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1508)
                                         at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7084)
                                         at android.view.Choreographer$CallbackRecord.run(Choreographer.java:927)
                                         at android.view.Choreographer.doCallbacks(Choreographer.java:702)
                                         at android.view.Choreographer.doFrame(Choreographer.java:638)
                                         at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913)
                                         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:6682)
                                         at java.lang.reflect.Method.invoke(Native Method)
                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
CantThinkOfAnything
  • 1,129
  • 1
  • 15
  • 40
  • 1
    The rest of the stack trace may help. – CommonsWare Jul 07 '17 at 17:23
  • Check out https://stackoverflow.com/questions/39111248/canvas-trying-to-draw-too-large-bitmap-when-android-n-display-size-set-larger and see if that helps. – D M Jul 07 '17 at 17:23
  • @CommonsWare I have added the the whole stacktrace of the error – CantThinkOfAnything Jul 07 '17 at 17:29
  • @DM I already looked through that question but I am not using Android N so the display setting does not apply. All other large images have been disabled from loading directly through XML. The only thing thats left is going through every other drawable that is set directly in XML and disabling it, no matter how small the image because only small icons are now being loaded like that. Everything else, I do it with Glide. – CantThinkOfAnything Jul 07 '17 at 17:31
  • 2
    What makes you say that images loaded with Glide should not be a problem? ~130MB is quite a large image. I haven't used Glide, but if it offers any sort of logging, enable it and see if it logs loading a large image. Other than the crash coming from an `ImageView`, the stack trace didn't help (I can see why you didn't include it originally). I can't think of a good way to get anything more from that. If you have enabled `android:largeHeap` in your manifest, disable it, and perhaps you will get an `OutOfMemoryError` at a spot that will help you track down where this large image is from. – CommonsWare Jul 07 '17 at 17:35
  • 1
    Find out which image has exactly 132710400 bytes size. That is the image killing your app. – Ali Jul 07 '17 at 17:38
  • Good suggestions guys, Ill see what I can do! Thanks – CantThinkOfAnything Jul 07 '17 at 17:54

1 Answers1

3

(I'm using Android Studio) ... To know which image it is, it takes a small bit of debugging. Do the following:

  1. First, run the app and allow it to crash.
  2. Look to the LOGCAT window. There you will find the crash: "java.lang.RuntimeException: Canvas: trying to draw too large(137080832bytes) bitmap." - Below that, look for "at android.graphics.drawable.BitmapDrawable.draw" and it will have a clickable link to the right. It should be the first clickable link displayed under the exception text above. Click the link.
  3. Clicking the link should highlight a line of code, likely the following:

    canvas.drawBitmap(bitmap, null, mDstRect, paint);

Set a breakpoint on that line of code. Then run the app again using the 'Debug app' button. The program will stop at the above line of code. You will need to click the 'Resume Program' button and keep track of how many times you click that button before the program crashes. Then run the app again in debug mode again, allow it to break on that line of code, then click the 'Resume Program' button the number of times you clicked the button previously, minus one time. So if I clicked the Resume Program button 4 times to get to the crash, you will want to click it 3 times and stop there. This will be the execution time of the code that causes the app to crash.

  1. The breakpoint for that line of code should be hit and the program halted, ready for you to do something. Hover the mouse over the word 'bitmap' in the line of code:

    canvas.drawBitmap(bitmap, null, mDstRect, paint);

Don't hover the mouse over the word 'drawBitmap' - just the word 'bitmap'. A small yellow window should appear below the line of code that contains a plus sign (+) and '{Bitmap@####}'. Click the plus sign. Notice that to the far right of the first line of text shown is a clickable link that reads 'View Bitmap'. Click on that link and you should be shown the picture that the app is trying and failing to load.

And that's it!

Will Buffington
  • 1,048
  • 11
  • 13
  • Hi WIll, thanks for leaving this answer. I posted this question a long time ago but its really great to see this method for finding that kind of bug. So upvote for you :D – CantThinkOfAnything May 02 '19 at 12:09
  • @Will Buffington THANK YOU! I've been searching for hours to try debugging which of my drawables was causing the throwIfCannotDraw crash on Galaxy S6. Your solution worked perfect! I found the culprit drawable, sized it accordingly, and no more crashes! – Joe Aug 10 '19 at 19:00