Android управляет изменениями конфигурации (состоянием) в пользовательском представлении

1

Это зависит от: локальная переменная Android get get потеряна при использовании намерения камеры

Правильный способ сделать это - обработать onSaveInstanceState и onRestoreInstanceState как показано здесь:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/CompoundButton.java

Вот мой код:

static class SavedState extends BaseSavedState
    {
        private String requestedFileName;
        private UUID[] mImages = new UUID[4];

        SavedState(Parcelable superState)
        {
          super(superState);
        }

        private SavedState(Parcel in)
        {
          super(in);
        }

        @Override
        public void writeToParcel(Parcel out, int flags)
        {
          super.writeToParcel(out, flags);
        }

        //required field that makes Parcelables from a Parcel
        public static final Parcelable.Creator<SavedState> CREATOR =
            new Parcelable.Creator<SavedState>()
            {
              public SavedState createFromParcel(Parcel in)
              {
                return new SavedState(in);
              }
              public SavedState[] newArray(int size)
              {
                return new SavedState[size];
              }
        };

    }

    @Override
    public Parcelable onSaveInstanceState()
    {
        //begin boilerplate code that allows parent classes to save state
        Parcelable superState = super.onSaveInstanceState();

        SavedState ss = new SavedState(superState);
        //end

        ss.requestedFileName = this.requestedFileName;
        ss.mImages = this.mImages;

        return ss;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state)
    {
        //begin boilerplate code so parent classes can restore state
        if(!(state instanceof SavedState))
        {
            super.onRestoreInstanceState(state);
            return;
        }

        SavedState ss = (SavedState)state;
        super.onRestoreInstanceState(ss.getSuperState());
        //end

        this.requestedFileName = ss.requestedFileName;
        this.mImages = ss.mImages;

        RestoreImageState();
    }

Теперь на мой вопрос. Этот код работает нормально, и он без проблем справляется со всеми изменениями состояния. ОДНАКО, если вы посмотрите на SavedState.writeToParcel и SavedState.SavedState, вы заметите, что я не храню здесь свои переменные. Должен ли я? Зачем? Проблема в том, что я понимаю, как сопоставить wrteToParcel и мои типы данных. Но чтение из посылки не так понятно со сложными типами. И в моих тестах он не назывался.

РЕДАКТИРОВАТЬ:

Правильно ли это выглядит для сохранения/восстановления порядка?

private SavedState(Parcel in)
        {
          super(in);
          this.mName = in.readString();
          this.mIndex = in.readInt();
          this.mApplicableDamages = (String[])in.readValue(null);
          this.mSelectedDamages = (boolean[])in.readValue(null);                            
        }

        @Override
        public void writeToParcel(Parcel out, int flags)
        {
          super.writeToParcel(out, flags);
          out.writeString(this.mName);
          out.writeInt(this.mIndex);
          out.writeArray(this.mApplicableDamages);
          out.writeBooleanArray(this.mSelectedDamages);
        }
Теги:

1 ответ

1
Лучший ответ

Вы должны сохранить эти переменные в onSaveInstanceState() и восстановить их в onRestoreInstanceState() позже, если они являются частью вашего состояния представления, и вы не хотите их потерять при воссоздании родительской активности.

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

Что касается написания сложных типов и чтения из Parcel вы можете реализовать Parcelable для некоторых частей сложного типа. Или вы можете просто разложить сложный тип на примитивные (разборные) поля и хранить эти поля один за другим. В вашем случае UUID[] может быть сохранен в Parcel как Serializable или вы можете преобразовать UUID[] в ParcelUuid[] и сохранить этот массив как разборный массив.

И несколько слов о реализации SavedState. Поля в SavedState не будут сохранены, если вы не добавите их в Parcel. Поэтому вам нужно написать метод Parcel в SavedState.writeToParcel(). А также вам нужно прочитать их в конструкторе SavedState(Parcel).

static class SavedState extends BaseSavedState
{
    private String requestedFileName;
    private UUID[] mImages = new UUID[4];

    SavedState(Parcelable superState)
    {
        super(superState);
    }

    private SavedState(Parcel in)
    {
        super(in);
        requestedFileName = in.readString();
        mImages = (UUID[])in.readSerializable();
    }

    @Override
    public void writeToParcel(Parcel out, int flags)
    {
        super.writeToParcel(out, flags);
        out.writeString(requestedFileName);
        out.writeSerializable(mImages);
    }

    //required field that makes Parcelables from a Parcel
    public static final Parcelable.Creator<SavedState> CREATOR =
        new Parcelable.Creator<SavedState>()
        {
            public SavedState createFromParcel(Parcel in)
            {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size)
            {
                return new SavedState[size];
            }
        };
}
  • 0
    Итак, мне нужно использовать SavedState.writeToParcel? А как продублировать поведение, когда оно будет называться?
  • 0
    Да, ты должен это назвать. И в этом методе вам нужно добавить все поля состояния в Parcel . Я не понимаю ваш вопрос о дублировании.
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню