mpountou
mpountou

Reputation: 838

How to catch RuntimeException

In my app i need to handle large bitmaps.Once i load my bitmap i want to show it in my imageview

                        try {
                            bitmap = GlideBitmapFactory.decodeFile(photoPath);                              
                        } catch (OutOfMemoryError) {
                           //i do stuff in order to load bitmap                  
                        }

My problem is that i can't catch java.lang.RuntimeException using the following try catch.

                            try {
                               ImageView i = (ImageView) findViewById(R.id.mainImageView);

                               i.setImageBitmap(bitmap);

                            } catch (Exception e) {
                               //never came here                 
                            }

Logcat:

 java.lang.RuntimeException: Canvas: trying to draw too large(116640000bytes) bitmap.
            at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)
            at android.graphics.Canvas.drawBitmap(Canvas.java:1415)
            at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:528)
            at android.widget.ImageView.onDraw(ImageView.java:1316)
            at android.view.View.draw(View.java:17214)
            at android.view.View.updateDisplayListIfDirty(View.java:16196)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.updateDisplayListIfDirty(View.java:16191)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.support.design.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1254)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.updateDisplayListIfDirty(View.java:16191)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.support.v4.widget.DrawerLayout.drawChild(DrawerLayout.java:1366)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.draw(View.java:17217)
            at android.view.View.updateDisplayListIfDirty(View.java:16196)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.updateDisplayListIfDirty(View.java:16191)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.updateDisplayListIfDirty(View.java:16191)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.updateDisplayListIfDirty(View.java:16191)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.updateDisplayListIfDirty(View.java:16191)
            at android.view.View.draw(View.java:16980)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3729)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3515)
            at android.view.View.draw(View.java:17217)
            at com.android.internal.policy.DecorView.draw(DecorView.java:757)
            at android.view.View.updateDisplayListIfDirty(View.java:16196)
            at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:648)
            at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:654)
            at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:762)
            at android.view.ViewRootImpl.draw(ViewRootImpl.java:2837)
            at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2645)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2252)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1291)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6396)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:876)
            at android.view.Choreographer.doCallbacks(Choreographer.java:688)
            at android.view.Choreographer.doFrame(Choreographer.java:623)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:862)
            at android.os.Handler.handleCallback(Handler.java:754)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:163)
            at android.app.ActivityThread.main(ActivityThread.java:6228)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

i know that Exception should catch RuntimeException. So what's going on?

Upvotes: 3

Views: 775

Answers (2)

Bek
Bek

Reputation: 8471

I think you're not catching exception that is thrown by this code. GlideBitmapFactory.decodeFile(photoPath). It's throwing runtime exception. Suggestion replace OutOfMemoryError with runtime exception. Use decodeFile(photoPath, 100, 100) to downsample the bitmap where second and third parameters are required width and height.

Upvotes: 0

TheWanderer
TheWanderer

Reputation: 17824

I believe it's because of this.

When you call setImageBitmap(), Android converts that bitmap to a Drawable and then internally calls setImageDrawable().

setImageDrawable() basically just updates a global variable (mDrawable) and then invalidates the ImageView. That means that you're no longer directly connected to the process of setting the image, as it seems to go through a Handler call, so you can no longer catch any Exception that's thrown.

You really should just scale the Bitmap before you set it instead of relying on the fact that it will throw an Exception.

Upvotes: 1

Related Questions