2011-08-24 5 views
1

Это следовать до: Android local variable get's lost when using camera intentAndroid управления изменениями конфигурации (состояния) в пользовательской точки зрения

Правильный способ сделать это, чтобы справиться с 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 и мои типы данных. Но чтение из посылки не так понятно со сложными типами. И в моих тестах он не назывался.

EDIT:

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

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

Вы должны сохранить эти переменные в 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? И как дублировать поведение, когда оно будет вызвано? – katit

+0

Да, вам нужно позвонить. И в этом методе вам нужно добавить все поля состояния в 'Parcel'. Я не понимаю ваш вопрос о дублировании. – Michael

+0

Когда я пишу на посылку - нет «тега» или «имени». Если я хочу сохранить, скажем, 2 строки. string1 и string2, а затем, когда мне нужно вернуть их в SavedState.SavedState - как узнать, какой из них? Путем дублирования я имею в виду, как я могу воспроизвести в эмуляторе или на устройстве, чтобы вызов writeToParcel получил? Как я сказал в ординарном посте - они никогда не вызываются в моем отладчике. И кажется, что все работает нормально – katit

Смежные вопросы