Saving Bundle with Android ComplexPreferences (JSon)

人走茶凉 提交于 2019-12-23 02:34:29

问题


This is a follow-on question from here: Save Bundle to SharedPreferences

I am trying to use the ComplexPreferences class from the aforementioned thread to save a Bundle object in my Android app, but to no avail! Here is the code I'm using to save and load the data to ComplexPreferences (much the same as in the example on the download page for the ComplexPreferences class):

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();

Class2:

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

The problem appears to be when saving the object to ComplexPreferences. Here is the stack trace I get when running the above code:

FATAL EXCEPTION: main java.lang.RuntimeException: Unable to pause activity {djb.ampersands/djb.ampersands.Ampersands}: java.lang.IllegalStateException: circular reference error 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) at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2794) at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2772) at android.app.ActivityThread.access$800(ActivityThread.java:130) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206) at 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) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalStateException: circular reference error 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) at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) at com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:147) at com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVisitor.java:127) at com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:114) at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) at com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:147) at com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVisitor.java:127) at com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:114) at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:62) at com.google.gson.BaseMapTypeAdapter.serialize(BaseMapTypeAdapter.java:34) at com.google.gson.MapTypeAdapter.serialize(MapTypeAdapter.java:53) at com.google.gson.MapTypeAdapter.serialize(MapTypeAdapter.java:33) at com.google.gson.JsonSerializationVisitor.findAndInvokeCustomSerializer(JsonSerializationVisitor.java:184) at com.google.gson.JsonSerializationVisitor.visitFieldUsingCustomHandler(JsonSerializationVisitor.java:204) at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:62) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:53) at 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) at djb.ampersands.Ampersands.onPause(Ampersands.java:93) at android.app.Activity.performPause(Activity.java:5106) at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1225) at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2825) ... 12 more Caused by: com.google.gson.CircularReferen

Since the object was saved incorrectly, it makes sense that I also get an error when trying to load the object again:

java.lang.IllegalArgumentException: Object storaged with key save is instanceof other class at djb.ampersands.gui.ComplexPreferences.getObject(ComplexPreferences.java:63)

Summary: When I first wrote this question, I said I couldn't get any objects to save/load correctly. However, I have now got this method to work for some objects, so really my question now is, can it ever work for Bundle objects, and the answer, it would appear, is no... so I guess it's back to the drawing board!


回答1:


You should not save your bundle entirely but only your gameState object. Bundles might be more complex to serialize than a simple POJO.

As the lib uses Json to serialize things, it expects a simple POJO and Bundles are definitely not simple POJOs : some fields of the Bundle class will never be serialized correctly in Json, especially the class loader.



来源:https://stackoverflow.com/questions/13665389/saving-bundle-with-android-complexpreferences-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!