Сохраните массив пользовательского объекта в состоянии экземпляра

У меня есть a List<CustomObject> (где CustomObject прибывает из внешней библиотеки - я не могу внести изменения в нее). Я хочу сохранить это в onSaveInstanceState(Bundle), но я, может казаться, не делаю это. Вот опции, которые я попробовал:

outState.putSerializable(KEY, (ArrayList<CustomObject>) myList); // because myList is instantiated as an ArrayList
outState.putSerializable(KEY, myList.toArray());

Обе опции работают при переключении ориентации по телефону (да, onSaveInstanceState назван при переключении ориентации - я зарегистрировался в logcat). Однако, когда текущее действие пытается запустить другой (с startActivity(Intent)), Android приостанавливает текущее действие и вызовы onSaveInstanceState() снова. На этот раз это перестало работать, по некоторым причинам неизвестный мне. Подозрительная вещь - это onSaveInstanceState() выполняется успешно. Распечатанное отслеживание стека не указывает ни на один мой код:

E/AndroidRuntime(23898): java.lang.RuntimeException: Parcel: unable to marshal value my.custom.Object@5e07e43b
E/AndroidRuntime(23898):    at android.os.Parcel.writeValue(Parcel.java:1087)
E/AndroidRuntime(23898):    at android.os.Parcel.writeArray(Parcel.java:519)
E/AndroidRuntime(23898):    at android.os.Parcel.writeValue(Parcel.java:1072)
E/AndroidRuntime(23898):    at android.os.Parcel.writeMapInternal(Parcel.java:469)
E/AndroidRuntime(23898):    at android.os.Bundle.writeToParcel(Bundle.java:1445)
E/AndroidRuntime(23898):    at android.os.Parcel.writeBundle(Parcel.java:483)
E/AndroidRuntime(23898):    at android.app.ActivityManagerProxy.activityPaused(ActivityManagerNative.java:1427)
E/AndroidRuntime(23898):    at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3106)
E/AndroidRuntime(23898):    at android.app.ActivityThread.access$2400(ActivityThread.java:119)
E/AndroidRuntime(23898):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870)
E/AndroidRuntime(23898):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(23898):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(23898):    at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime(23898):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23898):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(23898):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime(23898):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime(23898):    at dalvik.system.NativeStart.main(Native Method)

Там какой-либо путь состоит в том, чтобы хранить пользовательские объекты в состоянии экземпляра?

13
задан Felix 11 July 2010 в 12:25
поделиться

4 ответа

Сделайте свой CustomObject реализацией Parcelable и используйте:

outState.putParcelable(KEY, myList);
onSaveInstanceState(outState);

Также проверьте это руководство.

ИЗМЕНИТЬ после комментария CommonsWare:

Если ваш CustomObject не реализует Serializable или Parcelable , я бы попытался обернуть его внутри объекта своего собственного и добавьте:

  • private void readObject (ObjectInputStream aStream) выдает исключение IOException, ClassNotFoundException {/ * ваша десериализация * /}
  • private void writeObject (ObjectOutputStream aStream) выдает исключение IOException {/ * ваша сериализация * /}
6
ответ дан 2 December 2019 в 01:20
поделиться

Пусть ваш List будет храниться службой и сделать его доступным для ваших действий через локальный шаблон привязки.

Вам не только не нужно беспокоиться о том, чтобы удерживать его в состоянии вашего экземпляра, но вы немного лучше контролируете время жизни этих объектов в памяти. Время жизни состояния экземпляра контролируется Android; как долго служба удерживает объекты, контролируется вами. В частности, если CustomObject может быть большим или список может быть длинным, я бы предпочел, чтобы у вас был больший контроль над тем, как долго используется эта оперативная память.

5
ответ дан 2 December 2019 в 01:20
поделиться

Если это в первую очередь для обработки изменений ориентации, может ли Activity # onRetainNonConfigurationInstance () делать то, что вы хотите?

действие может использовать этот API для передачи расширенного состояния из старого экземпляра действия в новый, от загруженных растровых изображений до сетевых подключений и равномерно активных потоков. Обратите внимание, что вы не должны распространять какие-либо данные, которые могут измениться в зависимости от конфигурации, включая любые данные, загруженные из ресурсов, таких как строки, макеты или чертежи.

Этот API не поможет вам, если вы пытаетесь делать больше, чем просто сохранять данные при изменении конфигурации.

1
ответ дан 2 December 2019 в 01:20
поделиться

Почему бы просто не сохранить объект на SD-карту? Вы можете увидеть пример того, как я использую это в своем блоге >> http://androidworkz.com/2010/07/06/source-code-imageview-flipper-sd-card-scanner/

public void saveArray(String filename, String[] output_field) {
         try {
            FileOutputStream fos = new FileOutputStream(filename);
            GZIPOutputStream gzos = new GZIPOutputStream(fos);
            ObjectOutputStream out = new ObjectOutputStream(gzos);
            out.writeObject(output_field);
            out.flush();
            out.close();
         }
         catch (IOException e) {
             e.getStackTrace(); 
         }
      }

    public String[] loadArray(String filename) {
          try {
            FileInputStream fis = new FileInputStream(filename);
            GZIPInputStream gzis = new GZIPInputStream(fis);
            ObjectInputStream in = new ObjectInputStream(gzis);
            String[] read_field = (String[])in.readObject();
            in.close();
            return read_field;
          }
          catch (Exception e) {
              e.getStackTrace();
          }
          return null;
      }
-2
ответ дан 2 December 2019 в 01:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: