Пытаюсь сохранить и восстановить состояние с Activity
помощью методов onSaveInstanceState()
и onRestoreInstanceState()
.
Проблема в том, что он никогда не входит в onRestoreInstanceState()
метод. Может кто-нибудь объяснить мне, почему это так?
android
android-activity
states
BlaBRA
источник
источник
Ответы:
Обычно вы восстанавливаете свое состояние в
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"); } }
источник
onRestoreInstanceState()
вызывается только при воссоздании активности после того, как она была убита ОС. Такая ситуация бывает, когда:В отличие от этого: если вы находитесь в своей деятельности и
Back
нажимаете кнопку на устройстве, ваша деятельность будет завершена (т.е. думать об этом как о выходе из настольного приложения), и в следующий раз, когда вы запустите свое приложение, оно будет запущено «заново», т.е. сохраненное состояние, потому что вы намеренно вышли из него при удареBack
.Другой источник путаницы заключается в том, что когда приложение теряет фокус на другое приложение,
onSaveInstanceState()
вызывается, но когда вы переходите обратно к вашему приложению, онonRestoreInstanceState()
может не вызываться. Это случай, описанный в исходном вопросе, т.е. если ваша активность НЕ была убита в период, когда другая активность была впередиonRestoreInstanceState()
, НЕ будет вызываться, потому что ваша активность в значительной степени «живая».В целом, как указано в документации для
onRestoreInstanceState()
:Насколько я читал: нет причин переопределять,
onRestoreInstanceState()
если вы не подклассифицируете,Activity
и ожидается, что кто-то будет подклассифицировать ваш подкласс.источник
Состояние, в котором вы сохраняете,
onSaveInstanceState()
позже станет доступно приonCreate()
вызове метода. Поэтому используйтеonCreate
(и егоBundle
параметр), чтобы восстановить состояние вашей активности.источник
В качестве обходного пути вы можете сохранить пакет с данными, которые вы хотите поддерживать, в намерении, которое вы используете для запуска действия A.
Intent intent = new Intent(this, ActivityA.class); intent.putExtra("bundle", theBundledData); startActivity(intent);
Действие A должно передать это обратно в действие B. Вы должны получить намерение в методе onCreate действия B.
Intent intent = getIntent(); Bundle intentBundle; if (intent != null) intentBundle = intent.getBundleExtra("bundle"); // Do something with the data.
Другая идея состоит в том, чтобы создать класс репозитория для хранения состояния активности и чтобы каждое из ваших действий ссылалось на этот класс (возможно, используя одноэлементную структуру). Хотя это, вероятно, больше проблем, чем оно того стоит.
источник
Главное, что если не хранить
onSaveInstanceState()
тоonRestoreInstanceState()
не будет. Это основное различие междуrestoreInstanceState()
иonCreate()
. Убедитесь, что вы действительно что-то храните. Скорее всего это ваша проблема.источник
Я обнаружил, что onSaveInstanceState всегда вызывается, когда на передний план выходит другое Activity. И так же onStop.
Однако onRestoreInstanceState вызывался только тогда, когда также вызывались onCreate и onStart. И onCreate и onStart НЕ всегда вызывались.
Таким образом, похоже, что Android не всегда удаляет информацию о состоянии, даже если Activity перемещается в фоновый режим. Однако он вызывает методы жизненного цикла для сохранения состояния на всякий случай. Таким образом, если состояние не удалено, Android не вызывает методы жизненного цикла для восстановления состояния, поскольку они не нужны.
Рисунок 2 описывает это.
источник
Я думаю, эта ветка была довольно старой. Я просто упомянул еще один случай, который
onSaveInstanceState()
также будет вызван, когда вы позвонитеActivity.moveTaskToBack(boolean nonRootActivity)
.источник
Если вы обрабатываете изменения ориентации активности с помощью
android:configChanges="orientation|screenSize"
иonConfigurationChanged(Configuration newConfig)
,onRestoreInstanceState()
не будет вызываться.источник
Необязательно, чтобы onRestoreInstanceState всегда вызывался после onSaveInstanceState.
Обратите внимание, что: onRestoreInstanceState всегда будет вызываться при повороте активности (когда ориентация не обрабатывается) или при открытии вашей активности, а затем открытии других приложений, чтобы ваш экземпляр активности был удален из памяти ОС.
источник
Из документации Восстановление состояния пользовательского интерфейса активности с использованием сохраненного состояния экземпляра указано как:
ИМО, это более понятный способ, чем проверка на onCreate, и он лучше соответствует принципу единой ответственности.
источник
В моем случае он
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 }
источник