13

I'm developing a game using libgdx library.

When I load the program for the first time, the textures load perfectly and everything is fine

enter image description here

When I close the application, and load it again (I'm assuming Android is somehow caching it from memory) - the wrong textures get loaded.

enter image description here

If I clear the game from history, and try again, it works perfectly.

-- The way it works currently is as follows - I use a SpriteBatch to draw the actual game. I have seperate SpriteBatches to draw the background and Interface (which are loading just fine). On disposing a level, I dispose the SpriteBatch.

for (Block block : world.getDrawableBlocks(this.width, this.height))
        {
            spriteBatch.draw(block.getTexture(1f), block.getPosition().x, block.getPosition().y, block.SIZE_X, block.SIZE_Y);
        }

--

The textures I load using a cache I wrote myself to prevent the same image being loaded more than once. I clear the cache upon the creation of the application. I then keep a Texture / TextureRegion in the object itself, which is obtained through .getTexture()

And here's my code which I use to load the Textures

public static Texture loadTexture(String path)
    {
        //Do we have the texture cached?
        if (textures.containsKey(path))
        {
            //return it
            return textures.get(path);
        }
        else 
        {
            //load it from the filesystem
            Texture texture = new Texture(Gdx.files.internal(path));

            //cache it
            textures.put(path, texture);

            //return it
            return texture;


        }
    }

I attached a debugger and the textures being loaded DO have the correct path.

In the picture example, the texture being swapped happens to be part of the font, which is nothing which is EVER stored in my cache.

--

So, I'm rather stuck here.

Right now I'm using the naughty solution of killing the process manually on dispose:

 @Override
    public void onDestroy()
    {
        super.onDestroy();
        this.finish();
        android.os.Process.killProcess( android.os.Process.myPid()  ); 
    }

This works but is pretty dirty.

When the process fails due to an exception, the bug does not occur.


I'm guessing that somehow the library is caching its own textures which are somehow getting corrupted, but I have no idea how to check, nor how to clear them.

So, any ideas?

Haedrian
  • 4,240
  • 2
  • 32
  • 53
  • are you making textures or fonts static??? – Pranav008 Dec 24 '13 at 12:55
  • No, they're not static. – Haedrian Dec 24 '13 at 13:00
  • The TextureLoader cache I'm using is static however, but on application creation I specifically clear the hashmap I'm using. Do you think that could be an issue? – Haedrian Dec 24 '13 at 13:01
  • Do you load the textures in the main thread or do you have a custom thread for that? I wrote a custom thread to load the textures and they appeared broken, but nothing like this happened. Any concurrent loading might be the reason though. – Finnboy11 Jan 01 '14 at 11:08
  • I only use a single thread throughout the application. – Haedrian Jan 01 '14 at 11:19
  • Just for the sake of being 100% sure, instead of only 99.9999%: what are the exact String paths you use in your HashMap? Maybe, just maybe, there is hashcollision? – Martijn Courteaux Jan 02 '14 at 07:38

2 Answers2

2

You need to Dispose() all Textures you have created, for textures loop through all its value() and dispose it on a separate method then use that method in main game's screen dispose() function.

the switched texture seems is BitmapFont, and if those font textures used in UI, then you might have wrong in UI scene or so, also are you loading with JSON file?

seems to me that when you close the game your last texture is font texture is used, and it fills the texture is used on scene.

daniel
  • 697
  • 5
  • 15
  • And this is working for me. I went through my 'textureLoader' and disposed of all textures and the issue hasn't occured again. I guess it wasn't automatically disposing of them when the object itself was lost. – Haedrian Jan 02 '14 at 17:04
1

"new Texture", TextureAtlas, BitmapFont, etc are automatically reloaded after pause/resume or when the OpenGL context is otherwise lost.

I'm guessing your problem must be on the way you handle the manual reloading.

If you want to make sure that no texture is loaded more than once, use AssetManager instead. No need to do all that manually.

Daahrien
  • 10,190
  • 6
  • 39
  • 71
  • My issue is when the program is exited and opened again. I have no problems when the user pauses the application and continues it. When the user closes the application, does something else then opens it again - the issue occurs. Now the textures are actually created again (I followed with the debugger) and pass through the right pieces of code - just that when it arrives to drawing them... – Haedrian Dec 24 '13 at 18:56
  • Post the code where you first create them and when you reload them – Daahrien Dec 24 '13 at 22:52
  • How are you caching them? it seems the cached textures are being lost too. – Daahrien Dec 25 '13 at 00:10
  • I store them in a Hashmap. If I need the same texture I just return the one from memory instead of from the disk. But again, I clear the cache when I load the program, and I only have this issue when closing the program and opening again. I don't have this problem when loading levels or whatever. – Haedrian Dec 25 '13 at 07:23
  • I'm pretty sure your problem is that the textures in cache are being lost too. Don't cache them. Actually I don't think putting them in a hashmap counts as caching :p – Daahrien Dec 26 '13 at 21:18
  • I want them to be lost, so they can be re-created. Well, I do think its caching because some levels are loading 10 times faster, so something IS working. – Haedrian Dec 26 '13 at 21:34
  • I think I get you now. Try this: use AssetManager and load all the textures you will need, store them all in a class for example "myassets". And access them from there. ("myassets.playerwalk" for example). If you use Assetmanager you wont load a texture twice. And you will have them stored in a class(which isnt caching...). Your levels will load fast because they arent loaing the textures again. And you wont have this problem because they're recreated everytime the app starts. – Daahrien Dec 26 '13 at 21:41