2015-08-30 4 views
1

Я смотрю вокруг, но не могу найти ответ на этот точный вопрос.Почему в CODE Bundle и onSaveInstanceState Bundle разные фрагменты?

В деятельности это простая программа:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    if(savedInstanceState!=null)Log.e("SaveInstanceState", "onCreate Bundle " + savedInstanceState.hashCode()+" " + this.getClass().getSimpleName()); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    Log.e("SaveInstanceState", "onSaveInstanceState Bundle " + outState.hashCode()+" " + this.getClass().getSimpleName()); 

} 

приведет к следующему выходу (когда я поворачиваю ориентацию телефона):

E/SaveInstanceState﹕ onSaveInstanceState Bundle 1110617176 MainActivity 
E/SaveInstanceState﹕ onCreate Bundle 1110617176 MainActivity 

Same Bundle, следовательно, я могу легко пройти и восстановить данные.

Но во фрагменте, этот код:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if(savedInstanceState!=null)Log.e("SaveInstanceState", "onCreate Bundle " + savedInstanceState.hashCode()+" " + this.getClass().getSimpleName()); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    super.onCreateView(inflater,container, savedInstanceState); 
    if(savedInstanceState!=null)Log.e("SaveInstanceState", "onCreateView Bundle " + savedInstanceState.hashCode()+" " + this.getClass().getSimpleName()); 
    return inflater.inflate(R.layout.fragment_b, container, false); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    Log.e("SaveInstanceState", "onSaveInstanceState Bundle " + outState.hashCode()+" " + this.getClass().getSimpleName()); 

} 

Результаты в этом выводе:

E/SaveInstanceState﹕ onSaveInstanceState Bundle 1110622064 FragmentB 
E/SaveInstanceState﹕ onCreate Bundle 1110623448 FragmentB 
E/SaveInstanceState﹕ onCreateView Bundle 1110623448 FragmentB 

onSaveInstanceState Bundle и OnCreate различны, поэтому я потеряю данные, хранящиеся в onSaveInstanceState Bundle ,

У вас есть представление, что я делаю неправильно?

UPDATE

Ok благодаря @Sascha Кольберг, тот факт, что Bundle Hashcode отличается не означает, что Bundle пуст. Тогда встаньте вопрос:

Почему я не могу получить данные из Фрагмента onCreate Bundle?

Это то, что я делаю: "Здравствуйте!"

public class FragmentB extends Fragment { 

     public static final String USER_TEXT = "user_text"; 
     EditText userText; 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      super.onCreateView(inflater, container, savedInstanceState); 
      View layout = inflater.inflate(R.layout.fragment_b, container, false); 
      userText = (EditText) layout.findViewById(R.id.userText); 

      if (savedInstanceState != null) { 
       Log.e("SaveInstanceState", 
         "onCreateView savedInstanceState " + savedInstanceState + " " + this.getClass().getSimpleName()); 
       Log.e("SaveInstanceState", 
         "onCreateView savedInstanceState.getString(USER_TEXT) " + savedInstanceState.getString(USER_TEXT) + 
         " " + this.getClass().getSimpleName()); 
       userText.setText(savedInstanceState.getString(USER_TEXT)); 
      } 
      return layout; 
     } 

     @Override 
     public void onSaveInstanceState(Bundle outState) { 
      super.onSaveInstanceState(outState); 
      outState = new Bundle(); 
      outState.putString(USER_TEXT, String.valueOf(userText.getText())); 
      Log.e("SaveInstanceState", "onSaveInstanceState outState " + outState + " " + this.getClass().getSimpleName()); 
      Log.e("SaveInstanceState", 
        "onSaveInstanceState outState.getString(USER_TEXT) " + outState.getString(USER_TEXT) + " " + 
        this.getClass().getSimpleName()); 
     } 
    } 

Теперь я открываю мой телефон, написать в EditText, затем очистите logcat и измените ориентацию телефона с портретной на альбомную.

Выход следующим образом:

E/SaveInstanceState﹕ onSaveInstanceState outState Bundle[{user_text=Hello! }] FragmentB 
E/SaveInstanceState﹕ onSaveInstanceState outState.getString(USER_TEXT) Hello! FragmentB 
E/SaveInstanceState﹕ onCreateView savedInstanceState Bundle[{android:view_state={2131492945=TextView.SavedState{423430e0 start=5 end=5 text=Hello! locale=fr-FR}}}] FragmentB 
E/SaveInstanceState﹕ onCreateView savedInstanceState.getString(USER_TEXT) null FragmentB 

И EditText пуст после поворота телефона. Я думаю, что я мог бы получить данные, делая что-то вроде:

SparseArray p=savedInstanceState.getSparseParcelableArray("android:view_state"); 

в OnCreate метод, но это, кажется, действительно сложным.

Есть идеи?

ответ

1

Деятельность outStateBundle также содержит все состояния его дочерних фрагментов.

Итак, когда пучок проходит фрагмент в onSaveInstanceState(), он может передать своих братьев и сестер впоследствии, а в 'onCreate()' содержит больше, чем просто собственное состояние.

+0

Спасибо за комментарий, он поместил меня на дорожки. Моя активность теперь управляет состоянием его чидных фрагментов, передавая им Bundle в методе onCreate (фрагментB.setArguments ()), и он работает, но тогда я вообще не использую фрагмент onSaveInstanceState. Я не уверен, что это правильный способ, но он работает так ... зачем смотреть дальше. –

+0

Я не думаю, что вам нужно это сделать.Просто потому, что хэш-код пакетов отличается, не означает, что вы потеряете данные. Он отличается тем, что содержит ** больше ** данных, чем при регистрации в 'onSaveInstanceState'. На самом деле заглянули в комплект, имеются ли ваши данные? –

+0

Да, я заглянул внутрь и проверил его снова после вашего комментария. –