1
votes

I am having a problem with libGDX where when I resume the application after exiting with the back button, I get only a white screen.

The actual app runs, accepts touch input, and plays sounds, but the screen is just white.

I have read that keeping static references to Textures may cause this problem but I am not doing that.

Below is a simplified version of how my asset code works.

public class GdxGame extends Game {

    private Assets assets;

    @Override
    public void onCreate() {
        assets = new Asstes();
        assets.startLoading();

        /*
         *Within SplashScreen, GdxGame.getAssets() is accessed, and 
         *manager.update() is called
        */
        setScreen(new SplashScreen());
    }

    @Override
    public void dispose() {
        assets.dispose();
        assets = null;
    }

    //Perhaps a problem??
    public static Assets getAssets() {
        return ((GdxGame) Gdx.app.getApplicationListener()).assets;
    }
}

public class Assets implements Disposable{

    private AssetManager manager;

    public Assets() {
        manager = new AssetManager();
    }

    public void startLoading() {
        manager.load(....);
    }

    @Override
    public void dispose() {
        manager.dispose();
    }
}

Upon returning to the application after the back button is pressed, the AssetManager is recreated, the SplashScreen is reopened (as white), and the AssetManager updates until all assets are reloaded (takes about 2 seconds).

So when the application is reopened, a new AssetManager is loading all of the necessary textures, but for some reason everything is still white.

Could it have something to do with how I access the AssetManager from my UI and Game classes?

//In GdxGame
public Assets getAssets() {
    return ((GdxGame) Gdx.app.getApplicationListener()).assets;
}

That is the only place where I could see something going wrong, but even still, I don't understand what could be wrong with that.

Any help would be much appreciated.

Edit:

Here is the SplashScreen class. This makes the issue even more confusing. In the SplashScreen class I load, draw, and dispose a new Texture for the logo. Nothing to do with the AssetManager. Returning after the back button is pressed, this new Texture does not appear either.

public class SplashScreen extends Screen {
    private Texture logo;
    private Assets assets;

    @Override
    public void show() {
        assets = GdxGame.getAssets();

        logo = new Texture(Gdx.files.internal("data/logo.png"));
    }

    @Override
    public void render(float delta) {
        super.render(float delta);

        if(assets.load()) {
            //Switch screens
        }

        //getBatch() is the same form as getAssets() ((GdxGame) Gdx.app.getApplicationListener()).batch)
        GdxGame.getBatch().draw(logo, 100, 100, 250, 250);
    }

    @Override
    public void hide() {
        super.hide();
        logo.dispose();
    }
}
1
It would be great if you show us splashscreen class.And dont you use pause and resume events ?Deniz Yılmaz
@DenizYılmaz I'll add that in. I do use pause and resume events but not for anything to do with assets. Should something to do with assets be in these events? I'll add the SplashScreen class.matthewtory
You are talking about resuming the app so im pretty sure you must use resume event. Also u mention that you creating new assetmanager but i didnt see that in any assetmanager tutorial. i guess you can use this.assets; instead of ((GdxGame) Gdx.app.getApplicationListener()).assets;Deniz Yılmaz
@DenizYılmaz Well a new AssetManager is created because GdxGame.onCreate() is called again by the lifecycle, so it re-does the whole process. I can't use this.assets because getAssets() is a static method, so that won't work. The whole getApplicationListener() cast thing is essentially the same thing.matthewtory
Are you sure oncreate() calling when resume? because when you press back button , my libgdx game not totaly closing its just pausing actually. And i surprised when i saw onCreate. isn't it android method ?Deniz Yılmaz

1 Answers

1
votes

It turns out the issue was to do with how I was managing screens. I had a convenience method in my GdxGame class that allowed me to switch screens based on a ScreenType enum.

Within the enum, I would create a new screen with reflection, given the screen's class in the enum constructor.

The problem is that I stored the screens in the enums, and only created them once. This means that I was keeping and using screens from the old context when I returned after pressing back.

To solve this, I simply had to change it so that a new screen is created every time the enum is accessed, instead of storing one at the start.