0

In the onCreate() method of my Activity, I grab the outermost LinearLayout of the Activity's layout. I then check to see what the orientation of the phone is. If it is portrait, I set the background image of the LinearLayout to one image; if it is landscape, I set the background image of the LinearLayout to another image.

A user reported that if they open and close their hardware keyboard several times, the application will crash. The resulting log shows an OutOfMemoryError (bitmap size exceeds VM budget) error deep down in the bowels of setBackgroundResource called from onCreate().

Am I doing something wrong here? Is there a built in way to have Android handle this?

If it is useful, the log also shows about 2 dozen "unexpected resumes" just above the crash. This is the user opening and closing the hardware keyboard.

Andrew
  • 20,756
  • 32
  • 99
  • 177
  • Open/close keyboard causes an orientation change event which is probably reloading the bm background. If you are not disposing of your bm correctly that adds up, you probably are going to have to show some code to get a better handle on this. – Idistic Jul 20 '11 at 15:11

3 Answers3

1

Override the onConfigurationChange() method, since the changes in layout are handled with this method.

  @Override
    public void onConfigurationChanged(Configuration newConfig) {
            if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE)
            {
                //change of background 
            }
            else if(newConfig.orientation==Configuration.ORIENTATION_PORTRAIT)
            {
                //change the background
            }
                    else
                    { //do nothing, this might apply for the keyboard }


          super.onConfigurationChanged(newConfig);


        }


    }

and add this to your manifest

<activity android:name=".YourActivity"
         android:configChanges="keyboardHidden|orientation"                

                  android:label="@string/app_name">
Gopesh Gupta
  • 707
  • 8
  • 19
Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
  • http://developer.android.com/reference/android/content/res/Configuration.html What else you can try? Try saving your configuration in a public variable. Let say you started activity in horizontal orient. When your orient is changes to vertical, you just check with the new configuration in onConfigChngd(). P.S: try to use some of the method in the link above to compare. – Nikola Despotoski Jul 20 '11 at 15:44
  • No, no. I'm saying your solution worked. I'm still waiting to see what other people say before I decide this will be the solution I implement. I'm just letting you know it worked. – Andrew Jul 20 '11 at 15:50
  • Ow, good. :D I thought it didnt worked:D Good, good, I'm glad, I helped you. – Nikola Despotoski Jul 20 '11 at 15:58
1

When you load the background image in onCreate, save a reference to it. I'm assuming its a Bitmap, so in onDestroy call recycle on the Bitmap and you should be fine.

Femi
  • 64,273
  • 8
  • 118
  • 148
  • I'm calling setBackgroundResource, which takes a resource id. In my case, this is either R.drawable.background or R.drawable.background_landscape. – Andrew Jul 20 '11 at 15:32
  • What you might want to do is something in `onDestroy` like `View v = getTheView(); if(v.getBackground() != null && BitmapDrawable.class.isInstance(v.getBackground())) ((BitmapDrawable)v.getBackground()).getBitmap().recycle();` where `getTheView` returns the original View instance that you set the background on. – Femi Jul 20 '11 at 16:00
0

That happens because the previous image remains in memory until the garbage collector clean it, and everytime the user open an close the keyboard, a new activity is created and a new instance of an image is done. So to prevent that crash, clean the memory on your activity. Use what Femi said, in case it is a bitmap, or force a call to the garbage collector

Finuka
  • 730
  • 7
  • 15