我想保存项目的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
我做错了什么以及如何解决?
答案 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);
}
}