Search code examples
javaandroidlibgdxtexture2d

LibGDX: Slow loading Texture on android device (keep calling the garbage collector)


I'm building a game that need to have 27 animations in memory since i need to show them immediately after the user taped on the screen.

When running the desktop version of the app it's working fine but the loading time on an android device is too long (more then 3 minutes).

I can see that the garbage collector is being called a lot while the animations are loading (but they are still working after the it's done.)

this is the code i'm using to load the animation:

private static void loadLetterAnimation(String letter){
    Gdx.app.log("AssetLoader", "Loading letter animation for " + letter);
    Array currentLetterTextures = new Array();
    Array currentLetterTexturesRegions = new Array();
    FileHandle dirHandle = Gdx.files.internal("keys/animations/" + letter + "/");
    for (int j = 0; j < 30; j++) {
        Texture texture = new Texture(Gdx.files.internal("keys/animations/" + letter + "/" + j + ".png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        TextureRegion textureRegion = new TextureRegion(texture, 0, 0, texture.getWidth(), texture.getHeight());
        textureRegion.flip(false, true);
        currentLetterTextures.add(texture);
        currentLetterTexturesRegions.add(textureRegion);
    }
    Animation animation = new Animation(0.04f, currentLetterTexturesRegions);
    animation.setPlayMode(Animation.PlayMode.NORMAL);
    letterAnimationsTexturesMap.insert(letterAnimationsTexturesMap.size, letter, currentLetterTextures);
    letterAnimationsMap.insert(letterAnimationsMap.size, letter, animation);
}

and the logs are:

...
02-09 22:08:24.383  25272-25305/com.testing.android I/AssetLoader﹕ Loading letter animation for a
02-09 22:08:25.843  25272-25276/com.testing.android D/dalvikvm﹕ GC_CONCURRENT freed 373K, 16% free 9547K/11271K, paused 12ms+2ms, total 27ms
02-09 22:08:29.368  25272-25276/com.testing.android D/dalvikvm﹕ GC_CONCURRENT freed 405K, 16% free 9549K/11271K, paused 2ms+1ms, total 24ms
02-09 22:08:32.813  25272-25276/com.testing.android D/dalvikvm﹕ GC_CONCURRENT freed 400K, 16% free 9555K/11271K, paused 12ms+2ms, total 39ms
02-09 22:08:33.263  25272-25305/com.testing.android I/AssetLoader﹕ Loading letter animation for b
02-09 22:08:36.498  25272-25276/com.testing.android D/dalvikvm﹕ GC_CONCURRENT freed 397K, 16% free 9559K/11271K, paused 2ms+3ms, total 29ms
02-09 22:08:40.488  25272-25276/com.testing.android D/dalvikvm﹕ GC_CONCURRENT freed 454K, 16% free 9565K/11271K, paused 12ms+2ms, total 40ms
02-09 22:08:42.073  25272-25305/com.testing.android I/AssetLoader﹕ Loading    letter animation for c
02-09 22:08:45.323  25272-25276/com.testing.android D/dalvikvm﹕ GC_CONCURRENT freed 451K, 16% free 9567K/11271K, paused 12ms+2ms, total 39ms
...

Can someone please tell me what i'm doing wrong? is it even possible to do it?


Solution

  • Pack the textures into an Atlas (or set of atlases). This will improve load times because you'll look for fewer files, open fewer files, upload more data to the GPU in one go, and improve your run-time (by having fewer textures loaded, causing much less texture switching). See https://github.com/libgdx/libgdx/wiki/Texture-packer.

    The flip operation is also expensive. You should be able to setup your textures to be "flipped" in advance.

    Before doing that, its probably worth using one of the Heap Analysis tools to figure out where your memory and time are actually going. See http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html.