-2

There's three screens. The first is the main screen, the second is a filler screen and the third contains a screen with 4 buttons.

Main screen contains one button that leads to the 2nd screen, 2nd screen contains another button that leads to the 3rd screen.

Images are stored in drawable-hdpi.

The outofmemoryerror occurs when I press the button in the 2nd screen, specifically the android.app.Activity.setContentView in the onCreate on the 3rd screen.

The app works fine if it's only going from the 1st to the 3rd screen but we need to add some screens in between the 1st and 3rd screen.

Here's the logcat: enter image description here

Edit: I have a S4 (International) but it works fine on a Nexus 5.

dev2d
  • 4,245
  • 3
  • 31
  • 54

2 Answers2

0

It looks like you are loading a bitmap into memory. In an android app you only have about 16 megabytes of ram available, so you can run out of ram very quickly, and an outOfMemoryError will occur.

You can fix this by using the resource id of the image instead of a Bitmap object. For example, use:

setContentView(R.layout.view_id);

where view_id is the id of the view you want displayed.

  • How do I do that? I understand that in the xml, I'd give the xml an id but then what? What do I replace setContentView with?; Also, we're not ever working with any bitmap objects. – outofmemoryerror Nov 07 '14 at 21:18
  • There are 2 versions of setContentView, one which takes a View, and one which takes an integer. If you pass R.id.whatever into setContentView, it will work. –  Nov 07 '14 at 21:20
  • android:id="@+id/hello" in the xml and setContentView(R.id.hello); leads to an error? – outofmemoryerror Nov 07 '14 at 21:28
  • I'm using Android Studio so I'm assuming yes. I'll restart it. – outofmemoryerror Nov 07 '14 at 21:30
  • You should delete all R import, then alt-enter on the R.id.hello, and you will see several options. Choose the one with your package name. –  Nov 07 '14 at 21:31
  • Apparently, it was this error: http://stackoverflow.com/questions/24716385/android-studios-expected-resource-of-type-checks – outofmemoryerror Nov 07 '14 at 21:41
  • I tried the setContentView, it didn't work. Do you want to see the code to check it out for yourself? – outofmemoryerror Nov 07 '14 at 22:31
  • Yes, that would be really helpful. What kind of error are you getting this time? –  Nov 07 '14 at 22:32
  • Here it is: https://github.com/cryptogrammer/Air-Guitar/tree/master/app/src/main/java/com/example/utkarshgagrg/airguitar You don't need to worry about the myo, Main is the first screen, SyncoDeMyo is the 2nd, third is the Air. Line 23 of Synco is the trigger and line 203 of Air is where the actual crash happens. - this is without the new setContentView(int id) code though. – outofmemoryerror Nov 08 '14 at 03:34
  • I've looked at your code, and your drawables are huge. R.drawable.redchord, for example, is way too big. You can make them a lot smaller and it will work. –  Nov 08 '14 at 09:44
0

The use of images inside your activities can lead to occasional OutOfMemoryError, if you don't follow some guidelines.

First of all, take extreme attention when declaring, initializing and using Bitmaps inside you code. These objects are managed by the system in a special way, this is a good place to start if you want to use them efficiently.

Anyway, since you didn't post any code that show the use of Bitmaps, I focused the attention to a single line of your question:

Images are stored in drawable-hdpi.

Are the images stored ONLY in such directory? Well, this is a bad practice and it's a source of memory errors ;)

When you ask Android to initialize a particular Activity, all the images declared inside its XML are loaded from a particular drawable-**** folder, depending on the screen size of the current device. For example, a mdpi device will start to look inside the drawable-mdpi for the image named img. If it's not found, then it looks with a cascade behaviour inside all of the other drawable folders.

The problem is here: if the img is found in a different folder than drawable-mdpi, first it's scaled by the system to match the scaling factor for mdpi. Hence, another copy of the Bitmap is created.

Since all your images are inside a single, high resolution folder, the scaling operation will be executed by every non-hdpi device that will run your application. This is not good at all (here some docs).

The solution is to create different scaled versions of the same image and store them in multiple folders, like: drawable-ldpi, drawable-mdpi, drawable-hdpi, drawable-xhdpi

There is a convenient tool that does the dirty job: 9 Patch Resizer

TheUnexpected
  • 3,077
  • 6
  • 32
  • 62