Подтвердить что ты не робот

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

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

enter image description here

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

enter image description here

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

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

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

4b9b3361

Ответ 1

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

void onRestoreInstanceState (BundlevedInstanceState)

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

void onSaveInstanceState (Bundle outState)

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

Ответ 2

По doc1 и doc2

onSaveInstanceState

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

onRestoreInstanceState

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

Ответ 3

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

void onSaveInstanceState (Bundle outState)

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

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

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

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

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

Ответ 4

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

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

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

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

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

Ответ 5

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);
}