libGDX json错误

时间:2016-03-15 15:47:35

标签: json arraylist libgdx save

我想保存项目的Arraylist并保存并加载它。 这就是我想加载Arraylist的方法:

public static ArrayList<Item> inventory = new ArrayList<Item>();
 public mainscreen(final luckyllama gam) {
        game = gam;
        json = new Json();
        json.setIgnoreUnknownFields(true);
                 if(  json.fromJson(ArrayList.class,
                Gdx.files.internal("data/inventory.json")) != null){
                     ArrayList<JsonValue> list = json.fromJson(ArrayList.class,
                             Gdx.files.internal("data/inventory.json"));
                     for (JsonValue v : list) {
                         inventory.add(json.readValue(Item.class, v));
                     }
                 }
...

这是我保存Arraylist的方式:

mainscreen.json.toJson(mainscreen.inventory, Gdx.files.local("data/inventory.json"));

这是Item类的部分

public class Item {
    public float x, y, speedx, speedy;
    public Rectangle container, icontainer;
    public Sprite texture;
    public int Quality;
    static  int amount;
    static int spawned;
    public int itemtype;
    static Item item;

这是保存文件后的json文件:

[{
    class: com.algrande.luckyllama.Item,
    y: 50,
    speedx: -2.5,
    container: {
        y: 50,
        width: 50,
        height: 30
    },
    texture: {
        texture: {
            glTarget: 3553,
            glHandle: 1,
            minFilter: Linear,
            magFilter: Linear,
            uWrap: ClampToEdge,
            vWrap: ClampToEdge,
            data: {
                class: com.badlogic.gdx.graphics.glutils.FileTextureData,
                file: {
                    class: com.badlogic.gdx.backends.lwjgl.LwjglFileHandle,
                    file: {
                        path: items\\items.png
                    },
                    type: Internal
                },
                width: 4096,
                height: 4096,
                format: RGBA8888,
                pixmap: null,
                useMipMaps: false,
                isPrepared: false
            }
        },
        u: 0.25,
        u2: 0.5,
        v2: 0.25,
        regionWidth: 1024,
        regionHeight: 1024,
        vertices: [0,
        0,
        -1.7014117E38,
        0.25,
        0.25,
        0,
        0,
        -1.7014117E38,
        0.25,
        0,
        0,
        0,
        -1.7014117E38,
        0.5,
        0,
        0,
        0,
        -1.7014117E38,
        0.5,
        0.25],
        width: 1024,
        height: 1024,
        originX: 512,
        originY: 512
    },
    Quality: 1,
    itemtype: 62
}]

但是我收到了这个错误:

  Exception in thread "LWJGL Application" com.badlogic.gdx.utils.SerializationException: Error reading file: data/inventory.json
        at com.badlogic.gdx.utils.Json.fromJson(Json.java:694)
        at com.algrande.luckyllama.screens.mainscreen.<init>(mainscreen.java:78)
        at com.algrande.luckyllama.luckyllama.create(luckyllama.java:19)
        at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:147)
        at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)
    Caused by: com.badlogic.gdx.utils.SerializationException: Class cannot be created (missing no-arg constructor): com.badlogic.gdx.graphics.Texture
    Serialization trace:
    texture (com.badlogic.gdx.graphics.g2d.Sprite)
    texture (com.algrande.luckyllama.Item)
        at com.badlogic.gdx.utils.Json.newInstance(Json.java:1042)
        at com.badlogic.gdx.utils.Json.readValue(Json.java:892)
        at com.badlogic.gdx.utils.Json.readFields(Json.java:797)
        at com.badlogic.gdx.utils.Json.readValue(Json.java:919)
        at com.badlogic.gdx.utils.Json.readFields(Json.java:797)
        at com.badlogic.gdx.utils.Json.readValue(Json.java:919)
        at com.badlogic.gdx.utils.Json.readValue(Json.java:947)
        at com.badlogic.gdx.utils.Json.fromJson(Json.java:692)
        ... 4 more
    Caused by: com.badlogic.gdx.utils.reflect.ReflectionException: Could not instantiate instance of class: com.badlogic.gdx.graphics.Texture
        at com.badlogic.gdx.utils.reflect.ClassReflection.newInstance(ClassReflection.java:70)
        at com.badlogic.gdx.utils.Json.newInstance(Json.java:1024)
        ... 11 more
    Caused by: java.lang.InstantiationException: com.badlogic.gdx.graphics.Texture
        at java.lang.Class.newInstance(Class.java:427)
        at com.badlogic.gdx.utils.reflect.ClassReflection.newInstance(ClassReflection.java:68)
        ... 12 more
    Caused by: java.lang.NoSuchMethodException: com.badlogic.gdx.graphics.Texture.<init>()
        at java.lang.Class.getConstructor0(Class.java:3082)
        at java.lang.Class.newInstance(Class.java:412)
        ... 13 more

我做错了什么以及如何解决?

1 个答案:

答案 0 :(得分:2)

Json的自动反序列化依赖于空构造函数来实例化每个对象。 Json只能通过使用空构造函数来反序列化类。由于Item引用了一个引用纹理的Sprite;由于Texture没有任何空构造函数,因此无法自动反序列化Item。

所以你的选择是

1)在保存之前将精灵引用设置为null。然后将其切换回来。

2)删除Item类中Sprite的引用。而是将TextureRegion传递给Item的render方法(如果有)。

3)使用自定义Json序列化程序。您可以为Sprite分配一个不读取或写入任何内容的序列化程序。例如,在使用Json实例读取或写入之前执行此操作:

json.setSerializer(Sprite.class, new ReadOnlySerializer<Sprite>() {
    public Sprite read (Json json, JsonValue jsonData, Class type) {
        return (Sprite)null;
    }
}

然后你的Item类在加载之后需要一个精灵分配给它,可能是这样的:

public class Item {
    //...
    private String spriteName;

    //...

    /**Call this on every Item immediately after it has been loaded from Json. */
    public void onLoadedFromJson (TextureAtlas atlas){
        texture = atlas.createSprite(spriteName);
        sprite.setPosition(x, y);
    }
}