OnSaveInstanceState () и onRestoreInstanceState ()

Я пытаюсь сохранить и восстановить состояние Activity используя методы onSaveInstanceState() и onRestoreInstanceState() .

Проблема в том, что он никогда не входит в onRestoreInstanceState() . Может ли кто-нибудь объяснить мне, почему это?

Solutions Collecting From Web of "OnSaveInstanceState () и onRestoreInstanceState ()"

Обычно вы восстанавливаете свое состояние в onCreate() . Можно восстановить его и в onRestoreInstanceState() , но не очень часто. ( onRestoreInstanceState() вызывается после onStart() , тогда как onCreate() вызывается перед onStart() .

Используйте методы put для хранения значений в onSaveInstanceState() :

 protected void onSaveInstanceState(Bundle icicle) { super.onSaveInstanceState(icicle); icicle.putLong("param", value); } 

И восстановить значения в onCreate() :

 public void onCreate(Bundle icicle) { if (icicle != null){ value = icicle.getLong("param"); } } 

Вам не нужно сохранять состояния представления, поскольку они сохраняются автоматически , вызывая super.onSaveInstanceState (icicle) ;.

onRestoreInstanceState() вызывается только при восстановлении активности после того, как она была убита ОС. Такая ситуация возникает, когда:

  • Ориентация устройства изменяется (ваша деятельность уничтожается и воссоздается)
  • Есть еще одна активность перед вами, и в какой-то момент ОС убивает вашу активность, чтобы освободить память (например). В следующий раз, когда вы начнете свою деятельность onRestoreInstanceState() .

Напротив: если вы находитесь в своей деятельности, и вы нажимаете кнопку « Back на устройстве, ваша деятельность заканчивается () ed (т. Е. Думает об этом как о выходе из настольного приложения), и в следующий раз, когда вы запускаете приложение, оно запускается «свежим», т.е. Без сохранения состояния, потому что вы намеренно вышли из него, когда вы нажмете Back .

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

В целом, как указано в документации для onRestoreInstanceState() :

Большинство реализаций просто используют onCreate (Bundle) для восстановления своего состояния, но иногда удобно делать это здесь после завершения инициализации или разрешать подклассам решать, использовать ли вашу реализацию по умолчанию. По умолчанию реализация этого метода выполняет восстановление любого состояния представления, которое ранее было заморожено onSaveInstanceState (Bundle).

Когда я прочитал это: нет причин переопределять onRestoreInstanceState() если вы не выполняете подклассу Activity и ожидается, что кто-то подклассифицирует ваш подкласс.

Состояние, которое вы сохраняете на onSaveInstanceState() , позже доступно при onCreate() метода onCreate() . Поэтому используйте onCreate (и его параметр Bundle ), чтобы восстановить состояние вашей активности.

Я думаю, что эта тема была довольно старой. Я просто упоминаю еще один случай, что onSaveInstanceStatus() также будет вызываться, когда вы вызываете Activity.moveTaskToBack(boolean nonRootActivity) .

Главное, что если вы не храните в onSaveInstanceState() то onRestoreInstanceState() не будет вызываться. Это основное различие между restoreInstanceState() и onCreate() . Убедитесь, что вы действительно что-то хранили. Скорее всего, это ваша проблема.

Я обнаружил, что onSaveInstanceState всегда вызывается, когда на передний план выходит другое действие. И так onStop.

Однако onRestoreInstanceState вызывается только тогда, когда также вызывались onCreate и onStart. И, onCreate и onStart не всегда вызывались.

Таким образом, похоже, что Android не всегда удаляет информацию о состоянии, даже если Activity перемещается в фоновый режим. Тем не менее, он призывает методы жизненного цикла сохранять состояние только для того, чтобы быть в безопасности. Таким образом, если состояние не удалено, то Android не вызывает методы жизненного цикла для восстановления состояния, поскольку они не нужны.

Рисунок 2 описывает это.

В качестве обходного пути вы можете сохранить пакет с данными, которые вы хотите сохранить в намерении, которое вы используете для начала действия A.

 Intent intent = new Intent(this, ActivityA.class); intent.putExtra("bundle", theBundledData); startActivity(intent); 

Действия A должны будут передать это обратно в Activity B. Вы должны получить намерение в методе onCreate для Activity B.

 Intent intent = getIntent(); Bundle intentBundle; if (intent != null) intentBundle = intent.getBundleExtra("bundle"); // Do something with the data. 

Другая идея заключается в создании класса хранилища для хранения состояния активности, и каждый из ваших действий ссылается на этот класс (возможно, используя одноэлементную структуру.) Хотя, вероятно, это больше проблем, чем того стоит.

Если вы изменяете ориентацию ориентации деятельности с помощью android:configChanges="orientation|screenSize" и onConfigurationChanged(Configuration newConfig) , onRestoreInstanceState() не будет вызываться.

Не обязательно, чтобы onRestoreInstanceState всегда вызывался после onSaveInstanceState.

Обратите внимание, что: onRestoreInstanceState всегда будет вызываться, когда действие вращается (когда ориентация не обрабатывается) или откройте вашу активность, а затем откройте другие приложения, чтобы ваш экземпляр активности был очищен из памяти операционной системой.

В моем случае onRestoreInstanceState когда активность была восстановлена ​​после изменения ориентации устройства. onCreate(Bundle) был вызван первым, но у пакета не было ключа / значений, которые я установил с помощью onSaveInstanceState(Bundle) .

Сразу после этого, onRestoreInstanceState(Bundle) был вызван с пакетом, который имел правильный ключ / значения.

Я просто столкнулся с этим и заметил, что в документации есть мой ответ:

«Эта функция никогда не будет вызываться с нулевым состоянием».

https://developer.android.com/reference/android/view/View.html#onRestoreInstanceState(android.os.Parcelable)

В моем случае мне было интересно, почему onRestoreInstanceState не вызывалось при первоначальной инстанцировании. Это также означает, что если вы ничего не храните, это не будет вызвано, когда вы перейдете к восстановлению своего вида.

Я могу сделать это (извините, это c # не java, но это не проблема …):

 private int iValue = 1234567890; function void MyTest() { Intent oIntent = new Intent (this, typeof(Camera2Activity)); Bundle oBundle = new Bundle(); oBundle.PutInt("MYVALUE", iValue); //=> 1234567890 oIntent.PutExtras (oBundle); iRequestCode = 1111; StartActivityForResult (oIntent, 1111); } 

И В ВАШЕЙ ДЕЯТЕЛЬНОСТИ ДЛЯ РЕЗУЛЬТАТОВ

 private int iValue = 0; protected override void OnCreate(Bundle bundle) { Bundle oBundle = Intent.Extras; if (oBundle != null) { iValue = oBundle.GetInt("MYVALUE", 0); //=>1234567890 } } private void FinishActivity(bool bResult) { Intent oIntent = new Intent(); Bundle oBundle = new Bundle(); oBundle.PutInt("MYVALUE", iValue);//=>1234567890 oIntent.PutExtras(oBundle); if (bResult) { SetResult (Result.Ok, oIntent); } else SetResult(Result.Canceled, oIntent); GC.Collect(); Finish(); } 

В КОНЦЕ КОНЦОВ

 protected override void OnActivityResult(int iRequestCode, Android.App.Result oResultCode, Intent oIntent) { base.OnActivityResult (iRequestCode, oResultCode, oIntent); iValue = oIntent.Extras.GetInt("MYVALUE", -1); //=> 1234567890 }