【问题标题】:Saving Bundle with Android ComplexPreferences (JSon)使用 Android ComplexPreferences (JSon) 保存捆绑包
【发布时间】:2012-12-02 00:54:57
【问题描述】:

这是来自这里的后续问题:Save Bundle to SharedPreferences

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

1 类:

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 时。这是我在运行上述代码时得到的堆栈跟踪:

致命异常:main java.lang.RuntimeException:无法暂停 活动 {djb.ampersands/djb.ampersands.Ampersands}: java.lang.IllegalStateException:循环引用错误违规 字段:游戏违规对象:preserveType:false,类型: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) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:4745) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 在 dalvik.system.NativeStart.main(Native Method) 原因: java.lang.IllegalStateException:循环引用错误违规 字段:游戏违规对象:preserveType:false,类型: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) 在 com.google.gson.Gson.toJson(Gson.java:260) 在 com.google.gson.Gson.toJson(Gson.java:240) 在 djb.ampersands.gui.ComplexPreferences.putObject(ComplexPreferences.java:47) 在 djb.ampersands.Ampersands.onPause(Ampersands.java:93) 在 android.app.Activity.performPause(Activity.java:5106) 在 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 对象,而答案似乎是否定的......所以我想它又回到了绘图上板!

【问题讨论】:

  • 当您保存游戏数据打开您的 prefs 文件时,看起来您使用的是这个 same(我不推荐)键SAVE 但是当你取回你的对象时,看起来你正在使用两个不同的键 Ampersands.SAVEClass1.SAVE。我担心这些新值中的一个或多个可能与您保存它们时使用的字符串值不同。我认为您应该尝试暂时不要使用static,而只需使用普通的"string" 进行测试。此外,序列化仍然是一种选择^^
  • 这很难,因为你似乎混淆了很多东西。我的意思是你对你的类结构保密并且不显示堆栈跟踪。但我们需要这些信息,我认为他们不会泄露任何秘密……
  • 你可以试试: Object gameState = save.getObject(Ampersands.SAVE, Object.class);并检查 gameState 的类。
  • 对不起,AmpersandsClass1 一样,我只是为了简单起见而更改了它,但显然在一个实例中忘记了替换它。我并不是要通过混淆任何东西来混淆事物。类结构没有什么大秘密,它们只是 2 个独立的活动。我会尝试您的建议并使用堆栈跟踪编辑我的问题,但是从事物的声音来看,Bundles 可能对 Json 来说太复杂了 :(

标签: android json save bundle circular-reference


【解决方案1】:

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

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

【讨论】:

  • 我的gameState对象是一个Bundle,所以如果Bundles不能以这种方式保存,那么我想我又回到了我的原始问题。还是谢谢你们!
猜你喜欢
  • 1970-01-01
  • 2017-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
  • 2011-12-26
  • 2021-10-19
  • 2016-09-13
相关资源
最近更新 更多