3

我目前有以下课程:

 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 而不会出现 stackoverflowerror?

顺便提一句。正如大家所看到的,我之前没有问过这么多问题,所以如果您对如何改进我的问题有任何反馈:请告诉我!

编辑 1: 捆绑类是标准捆绑,fi:捆绑 args = new Bundle(); args.putint("someint", 1);

查看更新的堆栈跟踪...

编辑 2: 如果我采用一个 TabInfo 的单个实例,通过使用 String.class 作为参数,例如:

  TabInfo test= new TabInfo("test", String.class, new Bundle());
  String result=gson.toJson(test, hmType);

然后我得到以下堆栈跟踪:

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 < String, < Stack < TabInfo > > > 来做到这一点时,我又遇到了麻烦。我在这种情况下使用的 typetoken 是:

 Type hmType = new TypeToken<HashMap<String, Stack<TabInfo>>>(){}.getType();

所以,现在我的最后一个问题是:如何将 hashmap 中的一组 tabinfo-stacks 转换为 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 时,它会中断(内存不足......)......

4

1 回答 1

2

正如我建议将“从类更改”为字符串一样,
为了我们的读者,我允许自己在这里回答第一部分:
不要将类用作字段,而是使用包含完整类名的
字符串 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 可序列化类型。
这种模式也用在其他情况下,我建议你阅读更多关于数据传输对象的信息

于 2012-11-20T03:08:12.117 回答