Android: Parcelable.writeToParcel и Parcelable.Creator.createFromParcel никогда не называются - PullRequest
24 голосов
/ 31 января 2011

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

Потратив еще один день на попытки выяснить, почему это не работает, я решилобратиться за помощью, надеясь, что вы, ребята, можете дать мне несколько советов или, что лучше, решение.

Проблема: в игре для Android я пришел к тому, что я должен заставить приложение запомнить его состояниекогда пользователь, например, нажимает кнопку HOME-screen.После некоторых поисков я понял, что для того, чтобы мои классы инициализировались обратно в соответствующие состояния после повторного открытия приложения, мне пришлось поддерживать интерфейс Parcelable для передачи их с помощью Bundle.

В моих функциях onStop и onStartЯ соответственно сохраняю и восстанавливаю состояние игры в Bundle и из Bundle, однако, когда я вызываю функции putParcelable и getParcelable в Bundle, функции writeToParcel и createFromParcel объекта никогда не вызываются.

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

Основываясь на множестве примеров Parcelable, которые я видел в Интернете, это стало моим классом:

public class ParcelableTest implements Parcelable {
  int id;

  public ParcelableTest(int newID)
  {
    id = newID;
  }

  private ParcelableTest(Parcel in) {
      readFromParcel(in);
  }

  public void writeToParcel(Parcel out, int arg1) {
      writeToParcel(out);
  }

  public void writeToParcel(Parcel out) {
    Log.v("ParcelableTest","Writing to parcel");
      out.writeInt(id);
  }

  public void readFromParcel(Parcel in) {
      id = in.readInt();
  }

  public int describeContents() {
      return 0;
  }

  public static final Parcelable.Creator<ParcelableTest> CREATOR = new
  Parcelable.Creator<ParcelableTest>() {
      public ParcelableTest createFromParcel(Parcel in) {
          Log.v("ParcelableTest","Creating from parcel");
              return new ParcelableTest(in);
      }

      public ParcelableTest[] newArray(int size) {
              return new ParcelableTest[size];
      }
  };
}

И из моего основного занятия я бы вызвал следующие функции для сохранения / восстановления данных:

public Bundle saveToBundle(Bundle savedState)
    {
      savedState.putParcelable("Test1",mTest1);
      savedState.putParcelable("Test2",mTest2);
      return savedState;
    }
    public void restoreFromBundle(Bundle savedState)
    {
      mTest1 = savedState.getParcelable("Test1");
      mTest2 = savedState.getParcelable("Test2");

    }

Но по какой-то причине ни одна из функций (с функциями putParcelable и getParcelable) не приведет ксоответствующий Павызовы rcelable в моем тестовом классе.

Самое странное, что он каким-то образом читает правильные значения (я пробовал с большим количеством переменных в классе), но моя отладка и мой журнал показывают, что приложение никогда не попадает вwriteToParcel и createFromParcel.

Что мне здесь не хватает?

Буду признателен за любую помощь / мысли.

Ответы [ 3 ]

11 голосов
/ 14 апреля 2011

Очевидно, что класс Android Bundle не соответствует протоколу , который вместо этого используется во время сортировки IPC.

Вместо этого, похоже, что реализация Bundle просто записывает и считывает объект Parcelable в свою собственную внутреннюю карту посредством отражения. Из проведенного нами теста кажется, что Bundle записывает / читает каждое поле, определенное в вашем классе, производном от Parcelable, только потому, что вы объявили эти поля.

4 голосов
/ 08 июля 2013

Технически, в документации не сказано, что writeToParcel или createFromParcel вызываются из onSaveInstance. На самом деле, если вы проверите savedState в своем коде, вы обнаружите, что это абсолютно одинаковый экземпляр объекта как в случаях сохранения, так и в случаях восстановления; имеет смысл избегать сериализации-десериализации, если вы можете.
OTOH, документация также не говорит, что сериализация не выполнена. Следует сделать вывод, что вы не должны зависеть ни от одного случая, просто предположите, что вы получите правильный комплект.

Кроме того, вы можете проверить http://developer.android.com/guide/topics/resources/runtime-changes.html

0 голосов
/ 16 ноября 2013

Я подтверждаю, что сказал суперджос.В событии saveToBundle комплект Android просто хранит членов класса для каждого отражения и не вызывает функции Parcelable.Я потерял один день по этой проблеме!грустно ....

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

...