使用Android ComplexPreferences(JSon)保存捆绑包

时间:2012-12-02 00:54:58

标签: android json save bundle circular-reference

这是一个后续问题:Save Bundle to SharedPreferences

我正在尝试使用上述线程中的ComplexPreferences类来保存我的Android应用中的Bundle对象,但无济于事!下面是我用来保存和加载数据到ComplexPreferences的代码(与ComplexPreferences类的下载页面上的示例非常相似):

的Class1:

save = ComplexPreferences.getComplexPreferences(this, SAVE, MODE_PRIVATE);
...
Bundle gameState = new Bundle();
saveGameData(gameState); // This puts the game data into the Bundle
save.putObject(SAVE, gameState);
save.commit();

等级2:

save = ComplexPreferences.getComplexPreferences(this, Class1.SAVE, MODE_PRIVATE);
...
Bundle gameState = save.getObject(Class1.SAVE, Bundle.class);

将对象保存到ComplexPreferences时似乎存在问题。这是运行上面代码时得到的堆栈跟踪:

  

FATAL EXCEPTION:main java.lang.RuntimeException:无法暂停   活动{djb.ampersands / djb.ampersands.Ampersands}:   java.lang.IllegalStateException:循环引用错误Offending   field:game Offending object:preserveType:false,type:class   djb.ampersands.Ampersands,obj:djb.ampersands.Ampersands@41272778 at   android.app.ActivityThread.performPauseActivity(ActivityThread.java:2838)     在   android.app.ActivityThread.performPauseActivity(ActivityThread.java:2794)     在   android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2772)     在android.app.ActivityThread.access $ 800(ActivityThread.java:130)at   android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1206)     在android.os.Handler.dispatchMessage(Handler.java:99)at   android.os.Looper.loop(Looper.java:137)at   android.app.ActivityThread.main(ActivityThread.java:4745)at   java.lang.reflect.Method.invokeNative(Native Method)at   java.lang.reflect.Method.invoke(Method.java:511)at   com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:786)     在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)at   dalvik.system.NativeStart.main(Native方法)引起:   java.lang.IllegalStateException:循环引用错误Offending   field:game Offending object:preserveType:false,type:class   djb.ampersands.Ampersands,obj:djb.ampersands.Ampersands@41272778 at   com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:117)     在   com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69)     在com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120)     在   com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:147)     在   com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVisitor.java:127)     在   com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:114)     在   com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69)     在com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120)     在   com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:147)     在   com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVisitor.java:127)     在   com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:114)     在   com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69)     在com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120)     在   com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:62)     在   com.google.gson.BaseMapTypeAdapter.serialize(BaseMapTypeAdapter.java:34)     在com.google.gson.MapTypeAdapter.serialize(MapTypeAdapter.java:53)     在com.google.gson.MapTypeAdapter.serialize(MapTypeAdapter.java:33)     在   com.google.gson.JsonSerializationVisitor.findAndInvokeCustomSerializer(JsonSerializationVisitor.java:184)     在   com.google.gson.JsonSerializationVisitor.visitFieldUsingCustomHandler(JsonSerializationVisitor.java:204)     在   com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63)     在com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120)     在   com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:62)     在   com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:53)     在com.google.gson.Gson.toJsonTree(Gson.java:220)at   com.google.gson.Gson.toJson(Gson.java:260)at   com.google.gson.Gson.toJson(Gson.java:240)at   djb.ampersands.gui.ComplexPreferences.putObject(ComplexPreferences.java:47)     在djb.ampersands.Ampersands.onPause(Ampersands.java:93)at   android.app.Activity.performPause(Activity.java:5106)at   android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1225)     在   android.app.ActivityThread.performPauseActivity(ActivityThread.java:2825)     ... 12更多引起:com.google.gson.CircularReferen

由于对象保存不正确,因此在尝试再次加载对象时也会出错:

  

java.lang.IllegalArgumentException:使用密钥保存存储的对象是   其他课程的实例   djb.ampersands.gui.ComplexPreferences.getObject(ComplexPreferences.java:63)

摘要:当我第一次写这个问题时,我说我无法正确保存/加载任何对象。但是,我现在已经有了这个方法来处理某些对象,所以我现在真正的问题是,它能否适用于Bundle对象,答案看起来似乎不是......所以我想它就是这样。回到绘图板!

1 个答案:

答案 0 :(得分:3)

您不应该完全保存您的包,而只能保存您的gameState对象。序列化可能比简单的POJO更复杂。

由于lib使用Json来序列化事物,它需要一个简单的POJO和Bundles are definitely not simple POJOs:Bundle类的某些字段永远不会在Json中正确序列化,尤其是类加载器。