问题
I am using the libgdx AssetManager to load a skin with a custom font.
When I call assetmanager.dispose()
it throws an Exception:
com.badlogic.gdx.utils.GdxRuntimeException: Pixmap already disposed!
at com.badlogic.gdx.graphics.Pixmap.dispose(Pixmap.java:315)
at com.badlogic.gdx.graphics.g2d.PixmapPacker$Page$1.dispose(PixmapPacker.java:384)
at com.badlogic.gdx.graphics.g2d.BitmapFont.dispose(BitmapFont.java:315)
at com.badlogic.gdx.scenes.scene2d.ui.Skin.dispose(Skin.java:416)
at com.badlogic.gdx.assets.AssetManager.unload(AssetManager.java:211)
at com.badlogic.gdx.assets.AssetManager.clear(AssetManager.java:653)
at com.badlogic.gdx.assets.AssetManager.dispose(AssetManager.java:621)
while trying to dispose the custom font i added. I think that this is because the AssetManager disposes the BitmapFont first and the skin afterwards. But the skin is also trying to dispose the BitmapFont. Switching the order of loading the skin and the BitmapFont is not possible, because the skin needs the BitmapFont in its loading process.
This is where I load the skin and font:
FileHandleResolver resolver = new InternalFileHandleResolver();
app.assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
app.assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
FreetypeFontLoader.FreeTypeFontLoaderParameter params = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
params.fontFileName = "font/stay_writer.ttf";
params.fontParameters.size = 25;
app.assetManager.load("stay_writer_25.ttf", BitmapFont.class, params);
app.assetManager.finishLoading();
// Queue Skin
app.assetManager.load("skins/uiskin.atlas", TextureAtlas.class);
ObjectMap<String, Object> resources = new ObjectMap<String, Object>();
resources.put("default-font", app.assetManager.get("stay_writer_25.ttf", BitmapFont.class));
app.assetManager.load("skins/uiskin.json", Skin.class, new SkinLoader.SkinParameter("skins/uiskin.atlas", resources));
I am continiously calling assetmanager.update()
and made sure that the skin gets loaded.
I dispose the AssetManager with:
assetManager.dispose();
This gives me the Pixmap already disposed!
error.
I debugged the calls of BitmapFont.dispose()
. The stacktrace of the first call shows me that the call comes from assetManager.unload()
, and the second call from Skin.dispose()
which is called from the assetManager.unload()
method.
Now i want to know if there is a way to dispose of the skin and the BitmapFont, without them conflicting each other.
回答1:
It looks like SkinLoader does not tell AssetManager that the passed in resources
are dependencies, so if one of those resources is also a managed asset, it can lead to the problem you're getting.
So if you don't need the font to be managed by AssetManager, you could simply load it independently so AssetManager won't dispose of it.
Otherwise, I think you will need to remove the resource from the Skin before you unload or dispose of the Skin:
skin.remove("stay_writer_25.ttf", BitmapFont.class);
来源:https://stackoverflow.com/questions/39408448/assetmanager-and-skin-dispose-of-font-skin