Когда именно вызываются onSaveInstanceState() и onRestoreInstanceState()?

На следующем рисунке (из официального документа) описан известный жизненный цикл активности Android:

введите описание изображения здесь

С другой стороны, когда действие уничтожается системой (например, из-за необходимости восстановления памяти), состояние действия иногда автоматически сохраняется и восстанавливается с помощью методов. onSaveInstanceState() а также onRestoreInstanceState(), как показано на следующем рисунке (также из официального документа):

введите описание изображения здесь

Я знаю что onSaveInstanceState() не всегда вызывается, когда действие собирается быть уничтоженным. Например, если он уничтожен из-за того, что пользователь нажал кнопку "назад", состояние активности не сохраняется. Но в тех случаях, когда государство сохраняется и восстанавливается, и onSaveInstanceState() / onRestoreInstanceState() позвонить, когда именно они будут вызваны?

Например, согласно приведенным выше цифрам, onRestoreInstanceState() может быть вызван раньше onStart() или после onStart() но прежде onResume() или после onResume(), Точно так же существует несколько возможностей для onSaveInstanceState(), Так когда же они называются точно?

В идеале я хотел бы видеть комбинированную диаграмму, показывающую состояния жизненного цикла активности и методы сохранения / восстановления, если таковые существуют.

5 ответов

Решение

Согласно документации:

void onRestoreInstanceState (BundlevedInstanceState)

Этот метод вызывается между onStart() а также onPostCreate(Bundle),

void onSaveInstanceState (Bundle outState)

Если вызвано, этот метод будет происходить раньше onStop(), Там нет никаких гарантий о том, произойдет ли это до или после onPause(),

Не определено, когда onSaveInstanceState() можно назвать, единственная гарантия, которую мы имеем, это тот диапазон.

В соответствии с doc1 и doc2

onSaveInstanceState

До появления Honeycomb действия не считались подлежащими уничтожению до тех пор, пока они не были приостановлены, то есть onSaveInstanceState() был вызван непосредственно перед onPause(). Однако, начиная с Honeycomb, действия считаются уничтожаемыми только после их остановки, что означает, что onSaveInstanceState() теперь будет вызываться перед onStop(), а не непосредственно перед onPause().

onRestoreInstanceState

Этот метод вызывается между onStart () и onPostCreate(Bundle), когда действие повторно инициализируется из ранее сохраненного состояния.

В дополнение к уже опубликованным ответам в Android P внесено небольшое изменение, а именно:

void onSaveInstanceState (Bundle outState)

Если вызвано, этот метод будет происходить ПОСЛЕ onStop() для приложений, ориентированных на платформы, начиная с P. Для приложений, нацеленных на более ранние версии платформы, этот метод будет применяться раньше onStop() и нет никаких гарантий о том, произойдет ли это до или после onPause(),

Относительно того, почему это изменение введено, вот ответ:

... так что приложение может безопасно выполнять фрагменты транзакций в onStop() и сможет сохранить постоянное состояние позже.

Источник: документы

Это дополнительная информация для onSaveInstanceState(Bundle)

из документов

Не путайте этот метод с обратными вызовами жизненного цикла действия, такими как onPause(), который всегда вызывается, когда действие помещается в фоновом режиме или на пути к его уничтожению, или onStop(), который вызывается перед уничтожением. Один из примеров, когда onPause () и onStop() вызывается, а не этот метод, - это когда пользователь переходит от действия B к действию A: нет необходимости вызывать onSaveInstanceState(Bundle) для B, потому что этот конкретный экземпляр никогда не будет восстановлен Таким образом, система избегает вызывать его. Пример, когда вызывается onPause(), а не onSaveInstanceState(Bundle), - когда действие B запускается перед действием A: система может избежать вызова onSaveInstanceState(Bundle) для действия A, если оно не уничтожено в течение времени жизни B, так как состояние пользовательского интерфейса A останется без изменений.

Так что это реализация по умолчанию для..

Реализация по умолчанию заботится о большей части состояния пользовательского интерфейса для каждого экземпляра, вызывая onSaveInstanceState() для каждого представления в иерархии, имеющего идентификатор, и сохраняя идентификатор текущего сфокусированного представления (все из которых восстанавливается реализация по умолчанию onRestoreInstanceState(Bundle)). Если вы переопределите этот метод для сохранения дополнительной информации, не захваченной каждым отдельным представлением, вы, вероятно, захотите обратиться к реализации по умолчанию, в противном случае будьте готовы сохранить все состояния каждого представления самостоятельно.

String activityState;
@Override 
public void onCreate(Bundle savedInstanceState) {
// call the super class onCreate to complete the creation of activity like 
// the view hierarchy 
super.onCreate(savedInstanceState);

// recovering the instance state 
if (savedInstanceState != null) {
     activityState = savedInstanceState.getString(STATE_KEY);
 } 

   setContentView(R.layout.main_activity);
   mTextView = (TextView) findViewById(R.id.text_view);
} 

// Этот обратный вызов вызывается только тогда, когда есть сохраненный экземпляр, ранее сохраненный с помощью // onSaveInstanceState (). Мы восстанавливаем некоторое состояние в onCreate (), в то время как мы можем при желании восстановить // другое состояние здесь, возможно, используемое после завершения onStart (). // Bundle saveInstanceState такое же, как и в onCreate ().

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) {
 mTextView.setText(savedInstanceState.getString(STATE_KEY));
  } 


// invoked when the activity may be temporarily destroyed, save the instance 
//state here 
//this method will be called before onstop

@Override 
 public void onSaveInstanceState(Bundle outState) {
    outState.putString(STATE_KEY, activityState);

    // call superclass to save any view hierarchy 
    super.onSaveInstanceState(outState);
} 
Другие вопросы по тегам