1

I have three(ABC,PQR,XYZ) buttons in my UI, if i click any button then my application loads different images from drawable folder , but some time it gives OutOfMemory Exception. I am using the following code for loading images from Drawable folder.

      abc.setBackgroundResource(R.drawable.abc_on);
    pqr.setBackgroundResource(R.drawable.pqr_off);
    xyz.setBackgroundResource(R.drawable.xyz_off);

enter image description here

I am getting following exception in my logcat.

 E/AndroidRuntime(22116): java.lang.OutOfMemoryError
    E/AndroidRuntime(22116):    at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
    E/AndroidRuntime(22116):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
    E/AndroidRuntime(22116):    at    android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
    E/AndroidRuntime(22116):    at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
     E/AndroidRuntime(22116):   at android.content.res.Resources.loadDrawable(Resources.java:3024)
    E/AndroidRuntime(22116):    at android.content.res.Resources.getDrawable(Resources.java:1586)
     E/AndroidRuntime(22116):   at android.view.View.setBackgroundResource(View.java:16144)
   E/AndroidRuntime(22116):     at com.bloopit.fragments.ABCFragment.onClick(ABCFragment.java:242)

I am using Galaxy s4 device, and placed my images in xxhdpi folder and xml layout file is in layout folder. So, please guide me how to handle this. Thankyou.

koti
  • 1,071
  • 3
  • 15
  • 35

3 Answers3

0

Please check your image size and then check your device memory. May be it's happen because your device memory is low. Add this line in manifest and see the error is consist or not :

android:largeHeap="true"
Harshit Rathi
  • 1,862
  • 2
  • 18
  • 25
0

It may be how you are committing your transactions on each button click.

Consider a case when you have three buttons with each having its own fragment class. So when you click on button ABC, you added a transaction to the backstack with something like addToBackStack(null).commit().

Likewise you clicked button PQR, you added a transaction to the backstack again with addToBackStack(null).commit().

And same for XYZ.

Since the transactions are added repeatedly and in a wrong manner, the point will come when the stack will be full and there will be OOM exception.

First check the way you are adding the transactions to the backstack.

I faced the similar problem and what I did was to just remove the addToBackStack(null) thing before commit. This way you can assure that if it resolved the problem doing so.

Then you can better work on that particular thing to manage the transactions effectively. Obviously there are better ways to do so.

From whatever information you provided, it is almost not possible that only three resources can consume enough storage and give exceptions like OOM. There may be other parts in the application to consider further later.

You can also check for the available heap size with methods -

  • maxMemory()

    Runtime rt = Runtime.getRuntime();
    long maxMemory = rt.maxMemory();
    Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory));
    

It will tell you how many total bytes of heap your app is allowed to use before a hard error is triggered.

  • getMemoryClass()

    ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    int memoryClass = am.getMemoryClass();
    Log.v("onCreate", "memoryClass:" + Integer.toString(memoryClass));
    

It will tell you that how much heap should my app use, given the constraints of the Android OS version and hardware of the user's device.

  • getLargeMemoryClass()

As quoted on developer docs for getLargeMemoryClass-

Return the approximate per-application memory class of the current device when an application is running with a large heap. This is the space available for memory-intensive applications; most applications should not need this amount of memory, and should instead stay with the getMemoryClass() limit. The returned value is in megabytes. This may be the same size as getMemoryClass() on memory constrained devices, or it may be significantly larger on devices with a large amount of available RAM. The is the size of the application's Dalvik heap if it has specified android:largeHeap="true" in its manifest.

If you are specifically interested in determining the application heap size and want to understand that in detail consider seeing the detect-application-heap-size-in-android.

  • android:largeHeap="true"

    Use above in your manifest but--

Most apps should not need this and should instead focus on reducing their overall memory usage for improved performance. Enabling this also does not guarantee a fixed increase in available memory, because some devices are constrained by their total available memory.

Community
  • 1
  • 1
sjain
  • 23,126
  • 28
  • 107
  • 185
0

@Koti, I too faced this situation in my app which has various fragments and each fragment is having different back ground.So what i have done in my case is, i set the back ground in XML file only and the images in drawable should have as much as low memory. for this purpose use https://tinypng.com/. i am sure your problem will be solved with this. hope this will heps you.

GvSharma
  • 2,632
  • 1
  • 24
  • 30