【问题标题】:Assetmanager and Skin dispose of Font(/Skin)Assetmanager 和 Skin 处理字体(/Skin)
【发布时间】:2016-09-09 09:37:30
【问题描述】:

我正在使用 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.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 再配置皮肤。但是皮肤也在尝试处理BitmapFont。无法切换皮肤和 BitmapFont 的加载顺序,因为皮肤在加载过程中需要 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));

我不断致电assetmanager.update() 并确保皮肤已加载。

我使用以下方式处理 AssetManager:

assetManager.dispose();

这给了我Pixmap already disposed! 错误。
我调试了BitmapFont.dispose() 的调用。第一次调用的堆栈跟踪显示该调用来自assetManager.unload(),第二次调用来自Skin.dispose(),它是从assetManager.unload() 方法调用的。

现在我想知道是否有办法处理皮肤和 BitmapFont,而不会使它们相互冲突。

【问题讨论】:

    标签: java libgdx dispose


    【解决方案1】:

    看起来 SkinLoader 没有告诉 AssetManager 传入的 resources 是依赖项,因此如果其中一个资源也是托管资产,则可能会导致您遇到问题。

    因此,如果您不需要 AssetManager 管理字体,您可以简单地单独加载它,这样 AssetManager 就不会处理它。

    否则,我认为您需要在卸载或处置皮肤之前从皮肤中删除资源:

    skin.remove("stay_writer_25.ttf", BitmapFont.class);
    

    【讨论】:

    • assetManager.dispose() 方法为使用assetManager 加载的每个资产调用assetmanager.unload()。我测试了它,但它没有解决错误。处置其他资产后,我再次收到错误消息。
    • 啊,我明白了。从代码来看,SkinLoader 似乎将传入的resources 视为它们不受 AssetManager 管理。我会改变答案。
    • 对不起,我不明白你的回答。将其添加为依赖项或资源有什么区别?
    • 必须将其添加为皮肤资源,您的皮肤才能使用它。 AssetManager 中的依赖意味着 AssetManager 不会释放作为依赖的资产,直到依赖它的对象被卸载。但现在我想起来了,这仍然会导致你的字体被处理两次。我认为您唯一的选择是不直接将其添加到 AssetManager。答案已更新。
    • 我刚刚使用了try catch block。但我不喜欢这种方法。
    猜你喜欢
    • 1970-01-01
    • 2018-01-02
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    相关资源
    最近更新 更多