6
\$\begingroup\$

In an Android 2D game which is using SurfaceView where its onDraw is driven by a loop from a Thread, I use many bitmap sprites (sprite sheets) and two background size bitmaps, which are all loaded into memory at the start.

It all works fine, however, when the activity is onPause or after reloading it few times, Android shows a tendency to wipe out the big bitmaps only, probably to free memory. Sometimes this happens even in the middle of loading this very activity.

In order to counter this, I made a check in the onDraw method to test if the big bitmaps are still there and reload them if they are forcefully recycled by Android, before drawing them on Canvas.

This solution may not be the most stable, and since I know that there are much more accomplished android game programmers here than myself, I hope you can reveal some tricks or secrets or at least provide some good hints, how to overcome this.

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

The Android OS is only allowed to free up your memory while your application is halted with onPause(). You should be able to check for and load the assets during onResume() and then feel safe knowing they will be there until you get another onPause() callback.

Further reading:

\$\endgroup\$
5
  • \$\begingroup\$ Actually, I find that the Activity can lose its big bitmaps while it's loading and resizing them. Even while the game is going on, still the big bitmaps can just disappear. Maybe this is because my app is pushing it to the limit with the great number of bitmas, or there is a memory leak... \$\endgroup\$
    – Lumis
    Sep 6, 2012 at 10:24
  • \$\begingroup\$ I'm not aware of any cases where Android can "randomly" free up resources without going through the activity lifestyle. If the Android OS regularly did this you could imagine how bad of a platform it might be. \$\endgroup\$ Sep 6, 2012 at 19:28
  • \$\begingroup\$ You may have some bugs regarding asset management - perhaps some objects are getting garbage-collected because of a weird way you reference them, or your application isn't aware of configuration changes (portrait to landscape) or something. Some more reading that might ring bells: developer.android.com/guide/topics/resources/overview.html developer.android.com/guide/topics/resources/… \$\endgroup\$ Sep 6, 2012 at 19:30
  • \$\begingroup\$ I was reloading the same assets (bitmap background) into the same reference so that I can draw on them again the next level. When I do this few times only then fails to load the bitmaps. The most stable is if I restart the activity and so delete everything and start again... \$\endgroup\$
    – Lumis
    Sep 6, 2012 at 20:17
  • \$\begingroup\$ @TheMaster42 about your first comment... see this: stackoverflow.com/questions/12428493/… ! \$\endgroup\$
    – jmacedo
    Sep 22, 2012 at 1:28
0
\$\begingroup\$

The way to do it:

  • never create any new bitmaps unless you don't really have to, check every bit of the code

  • set the Activity on RGB_565, and especially the SurfaceView

getHolder().setFormat(0x00000004); //RGB_565

  • load bitmpas with

options.inPreferredConfig = Bitmap.Config.RGB_565;

RGB_565 is good enough for images with many details and SurfaceView runs almost twice faster in frame rates

  • use ARGB_4444 for small images in drop down lists etc, or anything that does not require very good quality

Have not had any out of memory errors in the same game after implementing this.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .