avi*_*vid 25 java android realm gson
我正在使用gson进行改造,将我的json反序列化为领域对象.这在大多数情况下都非常有效.处理时遇到麻烦
RealmList(String(或任何其他基本数据类型))
由于Realm不支持RealmList,其中E不扩展Realm对象,我将String包装在RealmObject中.
public class RealmString extends RealmObject {
private String val;
public String getValue() {
return val;
}
public void setValue(String value) {
this.val = value;
}
}
Run Code Online (Sandbox Code Playgroud)
我的领域对象如下
public class RealmPerson extends RealmObject {
@PrimaryKey
private String userId;
...
private RealmList<RealmString> stringStuff;
private RealmList<SimpleRealmObj> otherStuff;
<setters and getters>
}
Run Code Online (Sandbox Code Playgroud)
SimpleRealmObj工作正常,因为它只有String元素
public class SimpleRealmObj extends RealmObject {
private String foo;
private String bar;
...
}
Run Code Online (Sandbox Code Playgroud)
如何反序列化stringStuff?我尝试使用gson TypeAdapter
public class RealmPersonAdapter extends TypeAdapter<RealmPerson> {
@Override
public void write(JsonWriter out, RealmPerson value) throws IOException {
out.beginObject();
Log.e("DBG " + value.getLastName(), "");
out.endObject();
}
@Override
public RealmPerson read(JsonReader in) throws IOException {
QLRealmPerson rList = new RealmPerson();
in.beginObject();
while (in.hasNext()) {
Log.e("DBG " + in.nextString(), "");
}
in.endObject();
return rList;
}
Run Code Online (Sandbox Code Playgroud)
但是我仍然遇到了IllegalStateException
2334-2334/com.qualcomm.qlearn.app E // PersonService.java:71:main com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期字符串但在第1行第3行路径$为NAME.
我之前尝试过RealmList,RealmString适配器无济于事.到目前为止,我设法找到的唯一解决方法是https://github.com/realm/realm-java/issues/620#issuecomment-66640786 任何更好的选择?
Vic*_*ani 32
最好是使用JsonSerializer
和JsonDeserializer
,而不是TypeAdapter
你RealmObject
的,因为两个原因,:
它们允许您将(de)序列化委托RealmObject
给默认的Gson(de)序列化程序,这意味着您不需要自己编写样板文件.
在Gson 2.3.1中有一个奇怪的错误可能导致StackOverflowError
反序列化过程中(我TypeAdapter
自己尝试了这个方法并遇到了这个错误).
这是如何(替换Tag
你的RealmObject
班级):
(注:这context.serialize
和context.deserialize
下面是等价于gson.toJson
和gson.fromJson
,这意味着我们并不需要解析Tag
类的自己.)
解析器+序列化器RealmList<Tag>
:
public class TagRealmListConverter implements JsonSerializer<RealmList<Tag>>,
JsonDeserializer<RealmList<Tag>> {
@Override
public JsonElement serialize(RealmList<Tag> src, Type typeOfSrc,
JsonSerializationContext context) {
JsonArray ja = new JsonArray();
for (Tag tag : src) {
ja.add(context.serialize(tag));
}
return ja;
}
@Override
public RealmList<Tag> deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
RealmList<Tag> tags = new RealmList<>();
JsonArray ja = json.getAsJsonArray();
for (JsonElement je : ja) {
tags.add((Tag) context.deserialize(je, Tag.class));
}
return tags;
}
}
Run Code Online (Sandbox Code Playgroud)
标签类:
@RealmClass
public class Tag extends RealmObject {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用Gson注册转换器类:
Gson gson = new GsonBuilder()
.registerTypeAdapter(new TypeToken<RealmList<Tag>>() {}.getType(),
new TagRealmListConverter())
.create();
Run Code Online (Sandbox Code Playgroud)
错误消息" Expected a string but was NAME
"可以通过检索JsonReader
实际json对象(String
在您的情况下是一个)之前的json对象的名称来解决.
您可以查看JsonReader的Android文档.它有详细的解释和代码片段.您还可以查看readMessage
文档中示例代码段中的方法.
我已经将你的read
方法修改为我认为它应该是的.注意:我没有测试代码,因此可能会有一些小错误.
@Override
public RealmPerson read(JsonReader in) throws IOException {
RealmPerson rList = new RealmPerson();
in.beginObject();
String name = "";
while (in.hasNext()) {
name = in.nextName();
if (name.equals("userId")) {
String userId = in.nextString();
// update rList here
} else if (name.equals("otherStuff")) {
// since otherStuff is a RealmList of RealmStrings,
// your json data would be an array
// You would need to loop through the array to retrieve
// the json objects
in.beginArray();
while (in.hasNext()) {
// begin each object in the array
in.beginObject();
name = in.nextName();
// the RealmString object has just one property called "value"
// (according to the code snippet in your question)
if (name.equals("val")) {
String val = in.nextString();
// update rList here
} else {
in.skipValue();
}
in.endObject();
}
in.endArray();
} else {
in.skipValue();
}
}
in.endObject();
return rList;
}
Run Code Online (Sandbox Code Playgroud)
如果这有帮助,请告诉我.
归档时间: |
|
查看次数: |
16935 次 |
最近记录: |