我目前有以下课程:
static final class TabInfo{
public final String tag;
public final Class<?> clss;
public Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
我想创建json。 为此,我使用以下代码:
Gson gson= new Gson();
Type hmType= new TypeToken<TabInfo>(){}.getType();
String json = gson.toJson(methodToGetAnInstanceOfTabInfoClassHere, hmType);
当我这样做时,我得到一个java.lang.StackOverFlowError:
E/AndroidRuntime(10353): at Java.lang.StringBuffer.append(StringBuffer.java:219)
E/AndroidRuntime(10353): at java.io.StringWriter.write(StringWriter.java:147)
E/AndroidRuntime(10353): at com.google.gson.stream.JsonWriter.string(JsonWriter.java:519)
E/AndroidRuntime(10353): at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:387)
E/AndroidRuntime(10353): at com.google.gson.stream.JsonWriter.beginObject(JsonWriter.java:300)
E/AndroidRuntime(10353): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:190)
E/AndroidRuntime(10353): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrap E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(20692): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
所以,我的问题是:如何让我的gson从类TabInfo创建java对象的有效json而不会得到stackoverflower错误?
顺便说一下。你们所有人都可以看到,我之前没有问过这么多问题,所以如果你对如何改进我的问题有任何反馈意见:请告诉我!
编辑1: bundle类是标准的bundle,fi: Bundle args = new Bundle(); args.putint(&#34; someint&#34;,1);
请参阅更新的堆栈跟踪...
编辑2: 如果我通过使用String.class作为参数来获取TabInfo的单个实例,例如:
TabInfo test= new TabInfo("test", String.class, new Bundle());
String result=gson.toJson(test, hmType);
然后我得到以下stacktrace:
E/AndroidRuntime(22068): java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: java.lang.String. Forgot to register a type adapter?
E/AndroidRuntime(22068): at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:64)
E/AndroidRuntime(22068): at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:61)
E/AndroidRuntime(22068): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
E/AndroidRuntime(22068): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
E/AndroidRuntime(22068): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
E/AndroidRuntime(22068): at com.google.gson.Gson.toJson(Gson.java:586)
E/AndroidRuntime(22068): at com.google.gson.Gson.toJson(Gson.java:565)
E/AndroidRuntime(22068): at com.google.gson.Gson.toJson(Gson.java:520)
这是否意味着我需要为可能属于TabInfo类的所有24个不同的类创建一个TypeToken?我该如何解决这个问题?
编辑3
好的,感谢@Zaske,我找到了解决问题第一部分的方法。使用另一个类签名,如下所示
static final class TabInfo{
TabInfo(String _tag, String _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
现在我可以使用json,但是,当我尝试通过创建实际的HashMap&lt;字符串,&lt;堆栈&lt; TabInfo&gt; &GT; &GT;然后我再遇到麻烦。 我在这种情况下使用的typetoken是:
Type hmType = new TypeToken<HashMap<String, Stack<TabInfo>>>(){}.getType();
所以,现在我的最后一个问题是:如何将hashmap中的一组tabinfo-stack转换为json?
编辑4 以下是一些更多信息: 使用的Bundle类是Android中用于为活动和片段提供参数的Bundle类。 (见http://developer.android.com/reference/android/os/Bundle.html)
如果我这样做
TabInfo test= new TabInfo("test", "String", new Bundle());
//stage 1 test
String result=gson.toJson(test);
Log.d("new result=",result);
然后我得到了我的Json输出(见下文)
D/new result=(20816): {"args":{"mClassLoader":{"packages":{}},"mMap":{},"mHasFds":false,"mFdsKnown":true,"mAllowFds":true},"clss":"String","tag":"test"}
但是,当我尝试使用TabInfo类创建堆栈的Hashmap时,它会中断(内存不足......)......
答案 0 :(得分:1)
正如我建议“从课堂上改变”到字符串,为了让读者在第一部分回答这一点,我允许自己:
不要将Class用作字段,而是使用包含完整类名的String
TabInfo应如下所示:
static final class TabInfo{
public final String tag;
public final String clss;
public Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class.getName();
args = _args;
}
}
关于第二部分:
我不知道Bundle课程是什么 - 请提供信息,
因为我不得不改变一点并写自己的课程进行实验。
人类是:
public class Person implements Serializable {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public Person() {
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
private String name;
private int age;
}
检查的主要类别是:
public class Main {
public static void main(String[] args) {
Type type = new TypeToken<HashMap<String,Stack<Person>>>(){}.getType();
Gson gson = new Gson();
HashMap<String,Stack<Person>> map = new HashMap<String, Stack<Person>>();
map.put("yair", new Stack<Person>());
map.get("yair").add(new Person("Yair",36));
String str = gson.toJson(map,type);
System.out.println(str);
map = gson.fromJson(str,type);
String str2 = gson.toJson(map,type);
System.out.println(str2);
}
}
随意运行它,你会看到str和str2都打印得很好。
<强>更新强>
我查看了Bundle类,发现它包含太多信息(以我的拙见),是一个简单的参数集合。
我不明白为什么在上面的问题中不能使用简单的集合。
序列化应包含尽可能少的数据
(考虑将序列化数据存储在某些存储设备上或通过网络发送的情况)。
因此,除非Bundle为您提供集合不具备的特殊功能,否则请不要使用它。
根据经验记住,您不能使用Json序列化所有内容 - 有一些限制(例如递归数据类型) - 所以是的,有些情况下您必须从一种类型转换为JSON可序列化类型。
此模式也用于其他情况,我建议您阅读有关data transfer objects