Java Assetmanager和外观处理字体(/Skin)
我正在使用libgdx AssetManager加载带有自定义字体的外观 当我调用assetmanager.dispose()时,它会引发一个异常:Java Assetmanager和外观处理字体(/Skin),java,libgdx,dispose,Java,Libgdx,Dispose,我正在使用libgdx AssetManager加载带有自定义字体的外观 当我调用assetmanager.dispose()时,它会引发一个异常: com.badlogic.gdx.utils.GdxRuntimeException: Pixmap already disposed! at com.badlogic.gdx.graphics.Pixmap.dispose(Pixmap.java:315) at com.badlogic.gdx.graphics.g2d.PixmapPa
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)
在尝试处理我添加的自定义字体时。我认为这是因为AssetManager首先处理BitmapFont,然后处理皮肤。但是皮肤也在尝试处理位图字体。无法切换蒙皮和位图字体的加载顺序,因为蒙皮在加载过程中需要位图字体
这是我加载皮肤和字体的地方:
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));
这给了我Pixmap已经被释放了代码>错误。
我调试了BitmapFont.dispose()
的调用。第一个调用的堆栈跟踪显示该调用来自assetManager.unload()
,第二个调用来自Skin.dispose()
,该调用来自assetManager.unload()
方法
现在我想知道是否有一种方法可以处理skin和BitmapFont,而不会使它们相互冲突。看起来SkinLoader不会告诉AssetManager传入的资源是依赖项,因此如果其中一个资源也是托管资产,则可能会导致您遇到的问题
因此,如果您不需要AssetManager管理字体,只需单独加载它,AssetManager就不会处理它
否则,我认为您需要在卸载或处置皮肤之前从皮肤中移除资源:
skin.remove("stay_writer_25.ttf", BitmapFont.class);
assetManager.dispose()
方法为每个使用assetManager加载的资产调用assetManager.unload()
。我测试了它,但没有解决错误。一旦我处置了另一项资产,我又会犯错误。啊,我明白了。从代码看,SkinLoader似乎将传入的资源
视为不由AssetManager管理。我会改变答案的。对不起,我不明白你的答案。将其添加为依赖项或资源有什么区别?必须将其添加为皮肤资源,您的皮肤才能使用它。AssetManager中的依赖项意味着AssetManager在卸载依赖于它的对象之前不会处置依赖项资产。但是现在我想起来了,这仍然会导致你的字体被处理两次。我认为您唯一的选择是不直接将其添加到AssetManager。答案已更新。我刚刚使用了一个尝试catch block
。但我不喜欢这种方法。
skin.remove("stay_writer_25.ttf", BitmapFont.class);