- Overview
- Writing Object Graphs
- Reading Object Graphs
- Customizing Serialization
- Serialization Methods
- Event Based Parsing
Overview
libgdx can perform automatic object to JSON serialization and JSON to object deserialization. Four small classes make up the API:
-
JsonWriter
: A builder style API for emitting JSON. -
JsonReader
: Parses JSON and builds a DOM ofJsonValue
objects. -
JsonValue
: Describes a JSON object, array, string, float, long, boolean, or null. -
Json
: Reads and writes arbitrary object graphs usingJsonReader
andJsonWriter
.
To use these classes outside of libgdx, see the JsonBeans project.
Used to the default Android json.org library? Get started with this great tutorial.
Writing Object Graphs
The Json
class uses reflection to automatically serialize objects to JSON. For example, here are two classes (getters/setters and constructors omitted):
public class Person {
private String name;
private int age;
private ArrayList numbers;
}
public class PhoneNumber {
private String name;
private String number;
}
Example object graph using these classes:
Person person = new Person();
person.setName("Nate");
person.setAge(31);
ArrayList numbers = new ArrayList();
numbers.add(new PhoneNumber("Home", "206-555-1234"));
numbers.add(new PhoneNumber("Work", "425-555-4321"));
person.setNumbers(numbers);
The code to serialize this object graph:
Json json = new Json();
System.out.println(json.toJson(person));
{numbers:[{class:com.example.PhoneNumber,number:"206-555-1234",name:Home},{class:com.example.PhoneNumber,number:"425-555-4321",name:Work}],name:Nate,age:31}
That is compact, but hardly legible. The prettyPrint
method can be used:
Json json = new Json();
System.out.println(json.prettyPrint(person));
{
numbers: [
{
class: com.example.PhoneNumber,
number: "206-555-1234",
name: Home
},
{
class: com.example.PhoneNumber,
number: "425-555-4321",
name: Work
}
],
name: Nate,
age: 31
}
Note that the class for the PhoneNumber
objects in the ArrayList numbers
field appears in the JSON. This is required to recreate the object graph from the JSON because ArrayList
can hold any type of object. Class names are only output when they are required for deserialization. If the field was ArrayList<PhoneNumber> numbers
then class names would only appear when an item in the list extends PhoneNumber
. If you know the concrete type or aren't using generics, you can avoid class names being written by telling the Json
class the types:
Json json = new Json();
json.setElementType(Person.class, "numbers", PhoneNumber.class);
System.out.println(json.prettyPrint(person));
{
numbers: [
{
number: "206-555-1234",
name: Home
},
{
number: "425-555-4321",
name: Work
}
],
name: Nate,
age: 31
}
When writing the class cannot be avoided, an alias can be given:
Json json = new Json();
json.addClassTag("phoneNumber", PhoneNumber.class);
System.out.println(json.prettyPrint(person));
{
numbers: [
{
class: phoneNumber,
number: "206-555-1234",
name: Home
},
{
class: phoneNumber,
number: "425-555-4321",
name: Work
}
],
name: Nate,
age: 31
}
The Json
class can write and read both JSON and a couple JSON-like formats. It supports "JavaScript", where the object property names are only quoted when needed. It also supports a "minimal" format (the default), where both object property names and values are only quoted when needed.
Json json = new Json();
json.setOutputType(OutputType.json);
json.setElementType(Person.class, "numbers", PhoneNumber.class);
System.out.println(json.prettyPrint(person));
{
"numbers": [
{
"number": "206-555-1234",
"name": "Home"
},
{
"number": "425-555-4321",
"name": "Work"
}
],
"name": "Nate",
"age": 31
}
Reading Object Graphs
The Json
class uses reflection to automatically deserialize objects from JSON. Here is how to deserialize the JSON from the previous examples:
Json json = new Json();
String text = json.toJson(person);
Person person2 = json.fromJson(Person.class, text);
The type passed to fromJson
is the type of the root of the object graph. From this, the Json
class determines the types of all the fields and all other objects encountered, recursively. The "knownType" and "elementType" of the root can be passed to toJson
. This is useful if the type of the root object is not known:
Json json = new Json();
json.setOutputType(OutputType.minimal);
String text = json.toJson(person, Object.class);
System.out.println(json.prettyPrint(text));
Object person2 = json.fromJson(Object.class, text);
{
class: com.example.Person,
numbers: [
{
class: com.example.PhoneNumber,
number: "206-555-1234",
name: Home
},
{
class: com.example.PhoneNumber,
number: "425-555-4321",
name: Work
}
],
name: Nate,
age: 31
}
To read the JSON as a DOM of maps, arrays, and values, the JsonReader
class can be used:
Json json = new Json();
String text = json.toJson(person, Object.class);
JsonValue root = new JsonReader().parse(text);
The JsonValue
describes a JSON object, array, string, float, long, boolean, or null.
Customizing Serialization
Usually automatic serialization is desired and there is no need to customize how specific classes are serialized. When needed, serialization can be customized by either having the class to be serialized implement the Json.Serializable
interface, or by registering aJson.Serializer
with the Json
instance.
This example uses Json.Serializable
to write a phone number as an object with a single field:
static public class PhoneNumber implements Json.Serializable {
private String name;
private String number;
public void write (Json json) {
json.writeValue(name, number);
}
public void read (Json json, JsonValue jsonMap) {
name = jsonMap.child().name();
number = jsonMap.child().asString();
}
}
Json json = new Json();
json.setElementType(Person.class, "numbers", PhoneNumber.class);
String text = json.prettyPrint(person);
System.out.println(text);
Person person2 = json.fromJson(Person.class, text);
{
numbers: [
{
Home: "206-555-1234"
},
{
Work: "425-555-4321"
}
],
name: Nate,
age: 31
}
The class implementing Json.Serializable
must have a zero argument constructor because object construction is done for you. In the write
method, the surrounding JSON object has already been written. The read
method always receives a JsonValue
that represents that JSON object.
Json.Serializer
provides more control over what is output, requiring writeObjectStart
and writeObjectEnd
to be called if you require a JSON object like Json.Serializable
. Alternatively, a JSON array or a simple value (string, int, boolean) could be output instead of an object. Json.Serializer
also allows the object creation to be customized:
Json json = new Json();
json.setSerializer(PhoneNumber.class, new Json.Serializer<PhoneNumber>() {
public void write (Json json, PhoneNumber number, Class knownType) {
json.writeObjectStart();
json.writeValue(number.name, number.number);
json.writeObjectEnd();
}
public PhoneNumber read (Json json, JsonValue jsonData, Class type) {
PhoneNumber number = new PhoneNumber();
number.setName(jsonData.child().name());
number.setNumber(jsonData.child().asString());
return number;
}
});
json.setElementType(Person.class, "numbers", PhoneNumber.class);
String text = json.prettyPrint(person);
System.out.println(text);
Person person2 = json.fromJson(Person.class, text);
Serialization Methods
Json
has many methods to read and write data to the JSON. Write methods without a name string are used to write a value that is not a JSON object field (eg, a string or an object in a JSON array). Write methods that take a name string are used to write a field name and value for a JSON object.
writeObjectStart
is used to start writing a JSON object, then values can be written using the write methods that take a name string. When the object is finished, writeObjectEnd
must be called:
json.writeObjectStart();
json.writeValue("name", "value");
json.writeObjectEnd();
The writeObjectStart
methods that take an actualType and a knownType will write a class field to the JSON if the types differ. This enables the actual type to be known during deserialization. For example, the known type may be java.util.Map but the actual type is java.util.LinkedHashMap (which extends HashMap), so deserialization needs to know the actual type to create.
Writing arrays works in a similar manner, except the values should be written using the write methods that do not take a name string:
json.writeArrayStart();
json.writeValue("value1");
json.writeValue("value2");
json.writeArrayEnd();
The Json
class can automatically write Java object fields and values. writeFields
writes all fields and values for the specified Java object to the current JSON object:
json.writeObjectStart();
json.writeFields(someObject);
json.writeObjectEnd();
The writeField
method writes the value for a single Java object field:
json.writeObjectStart();
json.writeField(someObject, "javaFieldName", "jsonFieldName");
json.writeObjectEnd();
Many of the write methods take an "element type" parameter. This is used to specify the known type of objects in a collection. For example, for a list:
ArrayList list = new ArrayList();
list.add(someObject1);
list.add(someObject2);
list.add(someObject3);
list.add(someOtherObject);
...
json.writeObjectStart();
json.writeValue("items", list);
json.writeObjectEnd();
{
items: [
{ class: com.example.SomeObject, value: 1 },
{ class: com.example.SomeObject, value: 2 },
{ class: com.example.SomeObject, value: 3 },
{ class: com.example.SomeOtherObject, value: four }
]
}
Here the known type of objects in the list is Object, so each object in the JSON for "items" has a class field that specifies Integer or String. By specifying the element type, Integer is used as the known type so only the last entry in the JSON for "items" has a class field:
json.writeObjectStart();
json.writeValue("items", list, ArrayList.class, Integer.class);
json.writeObjectEnd();
{
items: [
{ value: 1 },
{ value: 2 },
{ value: 3 },
{ class: com.example.SomeOtherObject, value: four }
]
}
For maps, the element type is used for the values. The keys for maps are always strings, a limitation of how object fields are described using JSON.
Note that the Json
class uses generics on Java field declarations to determine the element type where possible.
Event Based Parsing
The JsonReader
class reads JSON and has protected methods that are called as JSON objects, arrays, strings, floats, longs, and booleans are encountered. By default, these methods build a DOM out of JsonValue
objects. These methods can be overridden to do your own event based JSON handling.
相关推荐
LibGDX是一个强大的开源游戏开发框架,用于创建跨平台的游戏。在这个主题中,我们主要探讨的是LibGDX中的全屏模式(FullScreen)和垂直同步(VSync)功能,这两个特性对于游戏性能和用户体验至关重要。 全屏模式...
LibGDX 提供了丰富的图形绘制功能,其中“Continuous & non continuous rendering”是两个重要的渲染模式,它们对于优化游戏性能和响应性至关重要。 **连续渲染(Continuous Rendering)** 连续渲染是一种实时更新...
LibGDX JSON是一个在LibGDX游戏开发框架中用于处理JSON(JavaScript Object Notation)数据的库。JSON是一种轻量级的数据交换格式,被广泛应用于网络通信和数据存储,因为它易于阅读和编写,同时也容易让机器解析和...
在"libgdx JSON(2)"这个主题中,我们将会深入探讨LibGDX框架中JSON库的高级用法,包括但不限于以下内容: 1. **JSON序列化与反序列化**: - 序列化是将Java对象转换为JSON字符串的过程,以便存储或传输。LibGDX...
标题“libgdx项目,json 还原为 csd”表明这个项目涉及将使用JSON格式存储的数据转换回CSD(可能指的是Custom Shape Data或某种特定的游戏资源格式)以便在LibGDX项目中使用。CSD格式通常是由游戏或特定工具自定义的...
本书“LibGDX Game Development Essentials”致力于为读者提供LibGDX游戏开发框架的核心知识,引导读者了解并掌握如何使用LibGDX来制作游戏。LibGDX是一个开放源码的Java游戏开发框架,它为游戏开发者提供了跨平台...
LibGDX 是一个开源的游戏开发框架,主要用于构建跨平台的2D和3D游戏。它为开发者提供了丰富的功能,使得游戏开发变得更加高效和便捷。在提供的"libGDX 1.10.0 开发包"中,包含了以下几个关键组件: 1. **gdx-1.10.0...
**LibGDX游戏开发详解** LibGDX是一个强大的开源Java框架,专为跨平台2D和3D游戏开发设计。这个框架允许开发者使用单一代码库创建游戏,可以在Android、iOS、Windows、Mac OS X和Linux等多个平台上运行。"libgdx...
6. **文件I/O**:LibGDX提供了方便的文件读写功能,包括读取JSON、XML等数据格式,便于资源管理和数据持久化。 7. **Scene2D**:一套高级的2D场景管理工具,包含UI组件、动画系统和粒子效果,让开发者可以快速构建...
《Libgdx开发丛书之 Learning LibGDX Game Development, 2nd Edition》是一本专为游戏开发者准备的图书,旨在帮助读者深入理解并熟练运用LibGDX这一强大的跨平台游戏开发框架。LibGDX是一个开源的Java库,支持在...
LibGDX是一个强大的开源游戏开发框架,用于创建跨平台的游戏。在LibGDX中,`Skin`类是一个非常重要的工具,它主要用于管理UI组件的外观和感觉,包括纹理、字体和样式。`Skin`类使得游戏开发者能够轻松地定义和应用...
LibGDX提供了Preferences类来存储简单的键值对数据,而更多的复杂数据可以使用JSON或XML序列化。 在这一系列的教程中,你将逐步学习如何使用上述技术和工具,从创建基本的Game类开始,搭建游戏结构,到设计游戏逻辑...
LibGDX是一个强大的开源游戏开发框架,主要用于创建跨平台的游戏。这个"LibGDX音频案例素材.zip"压缩包显然是为了教学或实践LibGDX中音频处理功能而准备的。让我们详细了解一下LibGDX的音频模块及其在游戏开发中的...
- **对应的精灵表(SpriteSheet JSON或XML)**:描述每个图像在纹理atlas中的位置和大小,便于在代码中使用。 - **测试代码**:展示如何在LibGDX项目中加载和使用由Texture Packer生成的纹理atlas。 在实际应用中,...
LibGDX是一个强大的开源游戏开发框架,用于创建跨平台的游戏。这个“libgdx1.6.1.rar”文件包含了LibGDX库的1.6.1版本,它是一个流行的Java库,支持开发者构建游戏,从Android到iOS,再到桌面平台如Windows、Linux和...
LibGDX是一个强大的开源游戏开发框架,它支持跨平台的游戏开发,包括Android、iOS、桌面系统(Windows、MacOS、Linux)以及Web浏览器。在这个"LibGDX Lua Tutorial工程"中,开发者可以学习如何利用LibGDX框架结合Lua...
《深入解析libgdx-1.6.1》 libgdx是一款强大的开源游戏开发框架,专注于跨平台的游戏开发,支持Android、iOS、HTML5、桌面应用等多种平台。本篇文章将详细探讨libgdx 1.6.1版本中的关键组件和特性,帮助开发者更好...
《蚂蚁回家》是一款基于Libgdx框架开发的开源游戏,展示了Libgdx的强大功能和灵活性。Libgdx是一个跨平台的游戏开发库,支持Windows、Linux、MacOS、Android以及iOS等多个操作系统,它提供了丰富的功能,使得开发者...
5. **文件I/O**:它提供了方便的数据读写接口,可以处理XML、JSON、图像、音频等资源。 6. **场景管理**:通过Scene2D库,开发者可以方便地构建2D游戏场景,包括舞台、演员、动作和动画等。 7. **网络通信**:...
Skin skin = new Skin(Gdx.files.internal("ui/uiskin.json")); LabelStyle labelStyle = skin.get("default-font", LabelStyle.class); Label myLabel = new Label("多行\n文本示例", labelStyle); ``` 最后,可能...