Сохранение пакета с Android ComplexPreferences (JSon)

Это дополнительный вопрос отсюда: Сохранить пакет в SharedPreferences

Я пытаюсь использовать класс ComplexPreferences из вышеупомянутого потока, чтобы сохранить объект Bundle в моем приложении для Android, но безрезультатно! Вот код, который я использую для сохранения и загрузки данных в 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. Вот трассировка стека, которую я получаю при запуске приведенного выше кода:

Поскольку объект был сохранен неправильно, логично, что я также получаю ошибку при попытке загрузить объект снова:

java.lang.IllegalArgumentException: объект, хранящийся с сохранением ключа, является экземпляром другого класса в djb.ampersands.gui.ComplexPreferences.getObject(ComplexPreferences.java:63)

Вывод: когда я впервые задал этот вопрос, я сказал, что не могу заставить какие-либо объекты правильно сохраняться/загружаться. Однако теперь у меня есть этот метод для работы с некоторыми объектами, поэтому на самом деле мой вопрос сейчас заключается в том, будет ли он когда-либо работать для объектов Bundle, и ответ, похоже, нет... так что я думаю, что вернемся к рисунку доска!

Вы не должны сохранять свой пакет полностью, а только свой объект

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();
. Пакеты могут быть более сложными для сериализации, чем простой POJO.


person Dan    schedule 02.12.2012    source источник
comment
Это сложно, потому что вы, кажется, многое запутываете. Я имею в виду, что вы держите свои структуры классов в секрете и не показываете трассировку стека. Но нам нужна эта информация, и я не думаю, что они раскроют какой-то секрет...   -  person mango    schedule 02.12.2012
comment
Не могли бы вы попробовать: Object gameState = save.getObject(Ampersands.SAVE, Object.class); и проверьте класс gameState.   -  person Snicolas    schedule 02.12.2012
comment
Извините, _1_ это то же самое, что и _2_, я просто изменил его для простоты, но, видимо, забыл заменить его в одном случае. Я не хотел запутать вещи, запутывая что-либо. В структуре класса нет большого секрета, это всего лишь 2 отдельных действия. Я попробую ваши предложения и отредактирую свой вопрос с помощью трассировки стека, но, судя по всему, Bundles может быть слишком сложным для обработки Json :(   -  person Snicolas    schedule 02.12.2012
comment
Мой объект gameState ЯВЛЯЕТСЯ Bundle, поэтому, если Bundles не могут быть сохранены таким образом, я думаю, что вернулся к своему первоначальному вопросу. Все же разрешите поблагодарить вас!   -  person Dan    schedule 02.12.2012


Ответы (1)


Поскольку библиотека использует Json для сериализации вещей, она ожидает простой POJO и пакеты определенно не простые POJO : некоторые поля класса Bundle никогда не будут корректно сериализованы в Json, особенно загрузчик классов.

когда вы сохраняете свои игровые данные и открываете файл настроек, похоже, что вы используете этот тот же (что я не рекомендую) ключ gameState Но когда вы получаете свой объект обратно , похоже, вы используете два разных ключа _2_ и _3_. меня беспокоит то, что одно или несколько из этих новых значений могут не представлять то же строковое значение, с которым вы их сохранили. Я думаю, вам следует попробовать не использовать _4_ немного, а просто использовать обычный _5_ для проверки. кроме того, сериализация все еще возможна ^^

person Snicolas    schedule 02.12.2012
comment
НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: основной java.lang.RuntimeException: невозможно приостановить активность {djb.ampersands/djb.ampersands.Ampersands}: java.lang.IllegalStateException: ошибка циклической ссылки Поле нарушения: игра Объект нарушения: saveType: false, тип: class djb .ampersands.Ampersands, obj: djb.ampersands.Ampersands@41272778 в 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(собственный метод ) в java.lang.reflect.Method.invoke(Method.j ava:511) в com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) в com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) в dalvik.system.NativeStart .main(собственный метод) Причина: java.lang.IllegalStateException: ошибка циклической ссылки Оскорбительное поле: игра Оскорбительный объект: saveType: 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(Jso nSerializationVisitor.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 (ReflectingFields). .gson.ObjectNavigator.accept(ObjectNavigator.java:120) в com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.jav a: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 - person Dan; 02.12.2012