What is savedinstancestate in android

Содержание
  1. Полный список
  2. OnSaveInstanceState and OnRestoreInstanceState in Android
  3. Before we start :
  4. First of all what is Instance State?
  5. But What?
  6. Why onSaveInstanceState() ?
  7. Then What is onRestoreInstanceState() ?
  8. Do we really need onRestoreInstanceState()
  9. Let’s see the Result :
  10. Как сохранить состояние активности Android с помощью сохранения состояния экземпляра?
  11. ОТВЕТЫ
  12. Ответ 1
  13. Ответ 2
  14. Ответ 3
  15. Ответ 4
  16. Храните локальные переменные/данные управления пользовательским интерфейсом для времени жизни приложения (т.е. временно), используя пакет состояния экземпляра
  17. Храните данные локальной переменной/управления пользовательским интерфейсом между экземплярами приложения (то есть постоянно), используя общие настройки
  18. Сохранение экземпляров объекта в памяти между действиями в течение времени жизни приложения с использованием сохраненного экземпляра без конфигурации
  19. Ответ 5
  20. Ответ 6
  21. Ответ 7
  22. Ответ 8
  23. Ответ 9
  24. Ответ 10
  25. Ответ 11
  26. Ответ 12
  27. Ответ 13
  28. Пример использования:
  29. Ответ 14
  30. Ответ 15
  31. Ответ 16
  32. Ответ 17
  33. Ответ 18
  34. Ответ 19
  35. Ответ 20
  36. Ответ 21
  37. Ответ 22
  38. Ответ 23
  39. Ответ 24
  40. Ответ 25
  41. Ответ 26
  42. Котлин
  43. График жизненного цикла
  44. Хранить переменные
  45. Получить переменные
  46. Ответ 27
  47. Ответ 28
  48. Добавление LiveData (компоненты архитектуры Android) в ваш проект
  49. Ответ 29
  50. Что сохранить, а что нет?
  51. Более подробная информация о onSavedInstanceState (Bundle saveinstaneState) при сохранении данных
  52. Какой выбрать для восстановления состояния активности?
  53. Подробнее о onRestoreInstanceState (Bundle saveinstaneState)
  54. бонус
  55. Соответствующие ссылки:
  56. Ответ 30

Полный список

— сохраняем данные при повороте экрана

Теорию по этому вопросу можно почитать тут. Я здесь вкратце дам вольный перевод.

Когда работа Activity приостанавливается(onPause или onStop), она остается в памяти и хранит все свои объекты и их значения. И при возврате в Activity, все остается, как было. Но если приостановленное Activity уничтожается, например, при нехватке памяти, то соответственно удаляются и все его объекты. И если к нему снова вернуться, то системе надо заново его создавать и восстанавливать данные, которые были утеряны при уничтожении. Для этих целей Activity предоставляет нам для реализации пару методов: первый позволяет сохранить данные – onSaveInstanceState, а второй – восстановить — onRestoreInstanceState.

Эти методы используются в случаях, когда Activity уничтожается, но есть вероятность, что оно еще будет востребовано в своем текущем состоянии. Т.е. при нехватке памяти или при повороте экрана. Если же вы просто нажали кнопку Back (назад) и тем самым явно сами закрыли Activity, то эти методы не будут выполнены.

Но даже если не реализовать эти методы, у них есть реализация по умолчанию, которая сохранит и восстановит данные в экранных компонентах. Это выполняется для всех экранных компонентов, у которых есть ID.

Создадим простое приложение, чтобы протестить все эти тезисы. Посмотрим, в какой момент вызываются эти методы, попробуем в них что-нить сохранить. Также убедимся, что необходимо вызывать соответствующие методы супер-класса, чтобы сохранялись данные экранных компонентов.

Т.к. нам надо будет поворачивать экран, используйте при разработке Android 2.2. В AVD с версией 2.3 поворот глючит.

Project name: P0701_SaveInstanceState
Build Target: Android 2.2
Application name: SaveInstanceState
Package name: ru.startandroid.develop.p0701saveinstancestate
Create Activity: MainActivity

В strings.xml пропишем тексты:

В main.xml нарисуем кнопку и пару полей для ввода текста:

Обратите внимание, что второй EditText без ID.

В MainActivity будем вызывать все методы Lifecycle и два вышеописанных:

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

Все сохраним и запустим. Введем в текстовые поля какие-нить данные:

и повернем экран CTRL+F12.

Данные в первом поле сохранились при повороте, а во втором пропали. Это произошло потому, что дефолтовые методы сохранения/восстановления умеют работать только с компонентами, которые имеют ID. Посмотрим лог.

Эти три метода выполнились при запуске.

Затем мы повернули экран:

onSaveInstanceState
onPause
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume

Первым делом вызывается onSaveInstanceState, здесь нам надо будет реализовывать сохранение своих данных. Далее идет уничтожение Activity (onPause, onStop, onDestroy) и создание нового onCreate, onStart. И перед onResume вызывается метод восстановления данных – onRestoreInstanceState.

Последовательность мы рассмотрели — сохраняются данные перед onPause, а восстанавливаются перед onResume. Попробуем теперь что-нибудь сохранить и восстановить. У нас на экране есть кнопка, будем по ее нажатию увеличивать счетчик нажатий на единицу и выводить всплывающее сообщение с итоговым кол-вом нажатий. Переменная cnt у нас уже есть. Реализуем onclick:

Повернем эмулятор обратно в вертикальную ориентацию. Запустим приложение, и жмем на кнопку Count. Видим сообщение с кол-вом нажатий. Нажмем еще несколько раз, получим, например 5.

Теперь повернем экран и снова нажмем кнопку.

Мы видим, что счетчик сбросился.

Это произошло потому, что текущий объект Activity был уничтожен и потерял значения всех переменных, в том числе и cnt. При создании нового Activity значение cnt равно 0 и отсчет пошел заново. Давайте это пофиксим. Реализуем метод сохранения onSaveInstanceState:

В объект outState мы пишем значение переменной cnt. Механизм аналогичен помещению данных в Intent.

Метод восстановления onRestoreInstanceState:

Из savedInstanceState вытаскиваем значение и помещаем в переменную cnt. Теперь при уничтожении и воссоздании Activity переменная cnt сохранит свое значение, и наш счетчик продолжит работать.

Проверим. Вернем AVD в вертикальную ориентацию. Все сохраним, запустим приложение. Понажимаем на кнопку, немного накрутим счетчик

и поворачиваем экран.

Жмем снова кнопку

счетчик не сбросился, а продолжил увеличиваться с последней позиции.

Итак, методы onSaveInstanceState и onRestoreInstanceState по дефолту сохраняют данные в экранных компонентах. Если мы реализуем их самостоятельно, то вызываем методы супер-класса и пишем свой код для своих переменных. Ради интереса, можете попробовать убрать вызовы методов суперкласса из onSaveInstanceState и onRestoreInstanceState. Данные в текстовом поле перестанут сохраняться при повороте экрана.

Кроме метода onRestoreInstanceState, доступ к сохраненным данным также можно получить в методе onCreate. На вход ему подается тот же самый Bundle. Если восстанавливать ничего не нужно, он будет = null.

Есть еще один полезный механизм сохранения данных. Android дает нам возможность сохранить ссылку на какой-либо объект и вернуть ее в новый созданный Activity. Для этого существуют методы:

onRetainNonConfigurationInstance – в нем мы сохраняем ссылку, передавая ее на выход (return) метода

Т.е., например, у нас есть какой то объект myObj (класс MyObject) и нам надо сохранить ссылку на него при повороте экрана.

Мы реализуем в Activity метод onRetainNonConfigurationInstance:

Этот метод будет вызван перед уничтожением Activity. От нас требуется дать на выход этому методу наш объект, который надо сохранить.

А, при создании нового Activity, в onCreate (например) мы используем метод getLastNonConfigurationInstance:

Мы получили обратно объект класса Object и привели его к нашему классу MyObject.

На следующем уроке:

— используем Preferences для работы с настройками приложения

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

OnSaveInstanceState and OnRestoreInstanceState in Android

Sep 30 · 5 min read

Hi Android Devs, Today I am going to explain about saving and restoring activity UI state using two important techniques; onSaveInstanceState and onRestoreInstanceState.

Before we start :

In this entire article I am taking the example of counter app, which will increment / decrement the counter value on button click.

First of all what is Instance State?

The term Instance State sounds difficult but don’t worry i will explain it in detail.

The normal activity behavior is that, a c tivity will be destroyed permanently when the user taps on the back button OR activity finishes itself by calling it’s finish() method. So, Next time when the same activity is re opened again then a whole new fresh activity will be created .

The life cycle callback of activity for the above behavior will be:

The above example shows normal app behavior, whenever user taps on back button intentionally, the activity will be destroyed permanently and if the same activity is opened again then the counter value (8) and name in the edittext is cleared. This is expected because back button on activity means that the user want to leave that activity, so no need to remember anything which was there previously ( counter value and name in edittext ).

But What?

What happens if the activity gets destroyed as a result of configuration change or process death. It’s not an expected behavior. So, the user may want to return to the same activity sooner and he might want the activity to have the same state (data entered in edit text, counter value ) as it was there before.

To achieve this android system will remember that the activity had existed before. So, when same activity is opened again ,then a fresh new activity will be created but with the remembered data / saved state ( counter value , name in the edittext ).

The saved data that is used to restore or retain the previous state of activity is called as instance state.

Читайте также:  Что такое аудиоканал андроид

The life cycle callback for the above behavior will be:

onPause() ➟ onStop() ➟ onSaveInstanceState() ➟ onDestroy() ➟ Same Activity Opened Again ➟ onCreate() ➟ onStart() ➟ onRestoreInstanceState() ➟ onResume()

On Pre Pie Devices OnSaveInstanceState() is called before onStop().

You can see two additional lifecycle callback methods above; onSaveInstanceState() and onRestoreInstanceState()

Let’s discuss them in the next section!

Why onSaveInstanceState() ?

When Activity undergoes configuration change or process death it is important to save the state of activity, so that when the same activity is opened in future with the same previous state.

By default the state of the view ( data in edit text, Listview scoll position ) is saved by the android system if the view has an ID. In this case onSaveInstanceState() is called internally by the android system.

But What if the user wants to save additional information (like counter value) that has to be the preserved even if the activity undergoes configuration change then developers has to override,

Here one can save simple primitive data in key-value pairs using Bundle object provided.

SCORE_KEY -> string key used to save counter value in bundle

countValue -> integer value which contains actual value of counter

Then What is onRestoreInstanceState() ?

In simple terms this method is used to restore state which is saved using onSaveInstanceState().

Remember that this callback will be called only if the activity is re opened after it had undergone configuration change or process death.

The view state which was saved automatically will be restored automatically by the android system by calling o nRestoreInstanceState() internally.

To restore the data saved by you , then you have to override,

Here we can make use of Bundle to retrieve saved data using keys.

SCORE_KEY -> string key used to retrive saved counter value in bundle

countValue -> integer variable which holds the counter value throughout the activity

Do we really need onRestoreInstanceState()

The answer is NO, Whaaaaaaaaat?

Yes we can even restore the saved state in o nCreate().

Remember the syntax of onCreate,

Here the savedInstanceState contains previous state saved using onSaveInstanceState().

if there are no previously saved states then the Bundle will be null; therefore we have to check whether savedInstanceState is null before retrieving the saved value.

Let’s see the Result :

Without saving Activity State (OnSave and OnRestore Instance State)

Here in the above example we are not using OnSaveInstanceState and OnRestoreInstanceState. You can see from the above video that whenever configuration change occurs (screen rotation) the counter value is not preserved / saved and therefore counter value = 0 after every screen rotation, because it is the default value we are assigning initially.

But the name in the edittext is not cleared ,why? because the system internally calls OnSaveInstanceState and OnRestoreInstanceState on VIEWS which has an ID.

Exercise for you: I will give you a small task….Create a simple edittext and don’t give any ID attribute to it. Try to rotate your device to see what happens?, do the same by giving ID to edittext.

With saving Activity State (OnSave and OnRestore Instance State)

Here we are using OnSaveInstanceState and OnRestoreInstanceState. You can see from the above video that whenever configuration change occurs (screen rotation) the counter value is preserved / saved and therefore counter value is same as it was before rotating the screen.

You can find full code in my github repository linked below;

Источник

Как сохранить состояние активности Android с помощью сохранения состояния экземпляра?

Я работал над платформой Android SDK, и немного неясно, как сохранить состояние приложения. Итак, учитывая этот незначительный повторный инструментарий примера «Hello, Android»:

Я думал, что этого будет достаточно для самого простого случая, но он всегда отвечает первым сообщением, независимо от того, как я ухожу от приложения.

Я уверен, что решение так же просто, как переопределение onPause или что-то в этом роде, но я onPause в документации около 30 минут и не нашел ничего очевидного.

ОТВЕТЫ

Ответ 1

Вам нужно переопределить onSaveInstanceState(Bundle savedInstanceState) и записать значения состояния приложения, которые вы хотите изменить, в параметр Bundle например так:

Bundle — это, по сути, способ хранения карты NVP («пара имя-значение»), и он передается в onCreate() а также в onRestoreInstanceState() где вы затем извлекаете значения следующим образом:

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

Ответ 2

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

Для более долгого состояния рассмотрите возможность использования базы данных SQLite, файла или настроек. См. Сохранение постоянного состояния.

Ответ 3

Обратите внимание, что НЕ безопасно использовать onSaveInstanceState и onRestoreInstanceState для постоянных данных, в соответствии с документацией по состояниям активности в http://developer.android.com/reference/android/app/Activity.html.

В документе указано (в разделе «Жизненный цикл активности» ):

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

Другими словами, введите код сохранения/восстановления для постоянных данных в onPause() и onResume() !

РЕДАКТИРОВАТЬ. Для дальнейшего уточнения здесь onSaveInstanceState() документация:

Этот метод вызывается до того, как действие может быть убито, так что когда оно возвращается в будущем, в будущем он может восстановить свое состояние. Для Например, если активность B запускается перед активностью A, а при некоторых точечная активность A убита для восстановления ресурсов, активность A будет возможность сохранить текущее состояние своего пользовательского интерфейса с помощью этого так что, когда пользователь возвращается к активности А, состояние пользовательский интерфейс можно восстановить с помощью onCreate(Bundle) или onRestoreInstanceState(Bundle) .

Ответ 4

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

В статье рассматриваются три подхода:

Храните локальные переменные/данные управления пользовательским интерфейсом для времени жизни приложения (т.е. временно), используя пакет состояния экземпляра

Храните данные локальной переменной/управления пользовательским интерфейсом между экземплярами приложения (то есть постоянно), используя общие настройки

Сохранение экземпляров объекта в памяти между действиями в течение времени жизни приложения с использованием сохраненного экземпляра без конфигурации

Ответ 5

Это классическая разработка для Android. Здесь есть два вопроса:

  • Существует тонкая ошибка Android Framework, которая значительно усложняет управление стеком приложений во время разработки, по крайней мере, в устаревших версиях (не совсем уверен, когда/когда/как это было исправлено). Я расскажу об этой ошибке ниже.
  • «Обычный» или предполагаемый способ решения этой проблемы сам по себе является довольно сложным с двойственностью onPause/onResume и onSaveInstanceState/onRestoreInstanceState

Просматривая все эти потоки, я подозреваю, что большую часть времени разработчики говорят об этих двух разных проблемах одновременно. следовательно, все путаницы и сообщения «это не работает для меня».

Во-первых, чтобы прояснить «предполагаемое» поведение: onSaveInstance и onRestoreInstance являются хрупкими и только для переходного состояния. Предполагаемое использование (afaict) — это обработка активности при повороте телефона (изменение ориентации). Другими словами, предполагаемое использование — это когда ваша активность по-прежнему логически «сверху», но все же должна быть восстановлена ​​системой. Сохраненный пакет не сохраняется за пределами процесса/памяти/gc, поэтому вы не можете положиться на это, если ваша деятельность переходит на задний план. Да, возможно, ваша память активности выдержит свою поездку на задний план и выйдет из GC, но это ненадежно (и это не предсказуемо).

Итак, если у вас есть сценарий, когда есть смысл «прогресса пользователя» или состояние, которое должно сохраняться между «запусками» вашего приложения, руководство должно использовать onPause и onResume. Вы должны сами выбрать и подготовить постоянный магазин.

НО — есть очень запутанная ошибка, которая усложняет все это. Подробности здесь:

В принципе, если ваше приложение запускается с флагом SingleTask, а затем вы запускаете его из главного экрана или меню запуска, то последующий вызов создаст новую задачу. у вас будет фактически два разных экземпляра вашего приложения, населяющего тот же стек. который очень странный очень быстро. Это происходит, когда вы запускаете свое приложение во время разработки (т.е. Из Eclipse или Intellij), поэтому разработчики часто сталкиваются с этим. Но также через некоторые механизмы обновления магазина приложений (так что это также влияет на ваших пользователей).

Я боролся через эти потоки в течение нескольких часов, прежде чем понял, что моя основная проблема — это ошибка, а не предполагаемое поведение структуры. Замечание и обходное решение (UPDATE: см. Ниже) похоже на пользователя @kaciula в этом ответе:

ОБНОВЛЕНИЕ Июнь 2013. Через несколько месяцев я наконец нашел правильное решение. Вам не нужно самостоятельно управлять любыми флагами с установленными состояниями, а вы можете обнаружить это из фреймворка и поручиться соответствующим образом. Я использую это в начале моего LauncherActivity.onCreate:

Читайте также:  Неполадки подключения или неверный код mmi android что это

Ответ 6

onSaveInstanceState вызывается, когда система нуждается в памяти и убивает приложение. Он не вызывается, когда пользователь просто закрывает приложение. Поэтому я думаю, что состояние приложения также должно быть сохранено в onPause Оно должно быть сохранено в каком-то постоянном хранилище, например Preferences или Sqlite

Ответ 7

Оба метода полезны и действительны, и оба они лучше всего подходят для разных сценариев:

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

Если вы сохраняете данные состояния постоянным образом, его можно перезагрузить в onResume() или onCreate() (или фактически на любом вызове жизненного цикла). Это может быть или не быть желательным. Если вы храните его в пакете в InstanceState , то он является временным и подходит только для хранения данных для использования в сеансе одного и того же пользователя (я использую термин сеанс свободно), но не между сеансами.

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

Ответ 8

Насколько я понимаю, сохранение состояния — в лучшем случае клудж. Если вам нужно сохранить постоянные данные, просто используйте базу данных SQLite. Android делает это СООО легко.

Что-то вроде этого:

Простой звонок после этого

Ответ 9

Я думаю, что нашел ответ. Позвольте мне рассказать, что я сделал простыми словами:

Предположим, что у меня есть два вида деятельности, activity1 и activity2, и я перемещаюсь из activity1 в activity2 (я сделал некоторые работы в activity2) и снова возвращаюсь к активности 1, нажимая на кнопку в Activity1. Теперь на этом этапе я хотел вернуться к активности2, и я хочу увидеть свою активность2 в том же состоянии, когда я последний раз оставил activity2.

В приведенном выше сценарии я сделал то, что в манифесте я сделал некоторые изменения следующим образом:

И в действии1 на событии нажатия кнопки я сделал вот так:

И в Activity2 при нажатии кнопки мыши я сделал следующее:

Теперь, что произойдет, так это то, что любые изменения, которые мы внесли в Activity2, не будут потеряны, и мы можем просмотреть activity2 в том же состоянии, в котором мы ранее были.

Я считаю, что это ответ, и это отлично работает для меня. Исправьте меня, если я ошибаюсь.

Ответ 10

onSaveInstanceState() для временных данных (восстановлено в onCreate() / onRestoreInstanceState() ), onPause() для постоянных данных (восстановлено в onResume() ). Из технических ресурсов для Android:

onSaveInstanceState() вызывается Android, если действие остановлено и может быть убито до его возобновления! Это означает, что он должен хранить любое состояние, необходимое для повторной инициализации в том же состоянии, когда операция перезапускается. Это аналог метода onCreate(), и на самом деле пакет savedInstanceState Bundle, переданный в onCreate(), представляет собой тот же Bundle, который вы создаете как outState в методе onSaveInstanceState().

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

Ответ 11

Восстанавливая активность

Существует несколько сценариев, в которых ваша деятельность уничтожается из-за обычного поведения приложения, например, когда пользователь нажимает кнопку «Назад», или ваша активность сигнализирует о своем собственном разрушении, вызывая finish() . Система также может уничтожить вашу деятельность, если она в настоящее время остановлена ​​и не использовалась в течение длительного времени, или для работы переднего плана требуется больше ресурсов, поэтому система должна отключить фоновые процессы для восстановления памяти.

Когда ваш activity уничтожается, потому что пользователь нажимает Назад или activity заканчивается, системная концепция этого экземпляра activity исчезает навсегда, потому что поведение указывает, что действие больше не требуется. Однако, если система уничтожает активность из-за системных ограничений (а не обычного поведения приложения), то, хотя фактический экземпляр Activity отсутствует, система помнит, что она существовала так, что если пользователь переходит к ней, система создает новый экземпляр действия с использованием набора сохраненных данных, который описывает состояние активности, когда он был destroyed . Сохраненные данные, которые система использует для восстановления предыдущего состояния, называются «состоянием экземпляра» и представляют собой набор пар ключ-значение, хранящихся в объекте Bundle.

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

Когда система начинает останавливать вашу деятельность, она вызывает onSaveInstanceState() (1), чтобы вы могли указать дополнительные данные состояния, которые вы хотите сохранить, в случае, если экземпляр Activity должен быть воссоздан. Если активность уничтожена и один и тот же экземпляр должен быть воссоздан, система передает данные состояния, определенные в (1), как методу onCreate() (2), так и методу onRestoreInstanceState() (3).

Сохранить состояние activity

По мере того, как ваша активность начинает останавливаться, система вызывает onSaveInstanceState() , поэтому ваша активность может сохранять информацию о состоянии с набором пар ключ-значение. Реализация этого метода по умолчанию сохраняет информацию о состоянии иерархии видов деятельности, например, текст в виджете EditText или в позиции прокрутки ListView .

Чтобы сохранить дополнительную информацию о состоянии вашей активности, вы должны реализовать onSaveInstanceState() и добавить пары ключ-значение в объект Bundle. Например:

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

Восстановить состояние activity

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

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

Например, здесь вы можете восстановить некоторые данные состояния в onCreate() :

Вместо восстановления состояния во время onCreate() вы можете реализовать onRestoreInstanceState() , который система вызывает после метода onStart() . Система вызывает onRestoreInstanceState() только в том случае, если для восстановления требуется сохраненное состояние, поэтому вам не нужно проверять, является ли Bundle равным null:

Ответ 12

Действительно onSaveInstance state callen, когда Activity переходит в фоновый режим

Цитата из документов: «метод onSaveInstanceState(Bundle) вызывается перед тем, как помещать активность в такое фоновое состояние»

Ответ 13

Чтобы помочь уменьшить шаблон, я использую следующие interface и class для чтения/записи в Bundle для сохранения состояния экземпляра.

Сначала создайте интерфейс, который будет использоваться для аннотирования переменных экземпляра:

Затем создайте класс, в котором отражение будет использоваться для сохранения значений в комплекте:

Пример использования:

Примечание. Этот код был адаптирован из проекта библиотеки с именем AndroidAutowire, который лицензируется под Лицензия MIT.

Ответ 14

Между тем я вообще больше не пользуюсь

Жизненный цикл для большинства видов деятельности слишком сложен и не нужен.

И Google заявляет о себе, это даже не надежно.

Мой способ — сохранить любые изменения сразу в настройках:

В некотором смысле SharedPreferences работают аналогично Bundles. И естественно и сначала такие значения нужно читать из предпочтений.

В случае сложных данных вы можете использовать SQLite вместо предпочтений.

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

Ответ 15

Чтобы ответить на исходный вопрос напрямую. savedInstancestate имеет значение null, потому что ваша активность никогда не воссоздается.

Ваша активность будет воссоздана только с помощью пакета состояний, когда:

  • Изменения конфигурации, такие как изменение ориентации или языка телефона, для которого может потребоваться создание нового экземпляра активности.
  • Вы вернетесь в приложение из фона после того, как ОС уничтожила действие.

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

При тестировании вашего примера hello world есть несколько способов уйти и вернуться к Activity.

  • При нажатии кнопки «Назад» действие завершено. Повторное запуск приложения — это новый экземпляр. Вы не возобновляете из фона вообще.
  • Когда вы нажимаете кнопку «домой» или используете переключатель задач, «Активность» переходит в фоновый режим. При переходе назад к приложению onCreate будет вызываться только в том случае, если действие должно быть уничтожено.
Читайте также:  Голосовая озвучка для андроид

В большинстве случаев, если вы просто нажимаете на кнопку «домой», а затем снова запускаете приложение, активность не нужно будет воссоздавать. Он уже существует в памяти, поэтому onCreate() не будет вызываться.

В разделе «Настройки» → «Параметры разработчика» есть опция «Не выполнять действия». Когда он активирует Android, он всегда будет уничтожать действия и воссоздавать их, когда они основываются. Это отличный вариант оставить включенным при разработке, поскольку он имитирует худший сценарий. (Устройство с низкой памятью постоянно перерабатывает ваши действия).

Другие ответы ценны тем, что они учат вас правильным способам хранения состояния, но я не чувствовал, что они действительно ответили. ПОЧЕМУ ваш код не работал так, как вы ожидали.

Ответ 16

Методы onSaveInstanceState(bundle) и onRestoreInstanceState(bundle) полезны для сохранения данных только при вращении экрана (изменение ориентации).
Они даже не хороши при переключении между приложениями (поскольку вызывается метод onSaveInstanceState() , но onCreate(bundle) и onRestoreInstanceState(bundle) снова не вызываются.
Для большей настойчивости используйте общие настройки. прочитайте эту статью

Ответ 17

Моя проблема заключалась в том, что я нуждался в постоянстве только в течение срока действия приложения (т.е. одно выполнение, включая запуск других под-действий в одном приложении и поворот устройства и т.д.). Я пробовал различные комбинации вышеупомянутых ответов, но не получал того, что хотел во всех ситуациях. В конце концов, что сработало для меня, было получить ссылку на savedInstanceState во время onCreate:

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

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

Ответ 18

Несмотря на то, что принятый ответ верен, существует более быстрый и простой способ сохранить состояние активности на Android с помощью библиотеки Icepick. Icepick — это обработчик аннотации, который заботится обо всех шаблонах, используемых для сохранения и восстановления состояния.

Выполнение чего-то подобного Icecick:

То же самое, что и при этом:

Icepick будет работать с любым объектом, который сохраняет свое состояние с помощью Bundle .

Ответ 19

Когда создается действие, вызывается метод onCreate().

savedInstanceState является объектом класса Bundle, который является null в первый раз, но он содержит значения при его воссоздании. Чтобы сохранить состояние активности, вы должны переопределить onSaveInstanceState().

поместите свои значения в объект «outState» Bundle, такой как outState.putString( «ключ», «приветствие назад» ) и сохраните, вызвав super. Когда активность будет уничтожена, состояние будет сохранено в объекте Bundle и может быть восстановлено после отдыха в onCreate() или onRestoreInstanceState(). Пакет, полученный в onCreate() и onRestoreInstanceState(), одинаковый.

Ответ 20

Существует два способа реализовать это изменение.

  • с помощью onSaveInstanceState() и onRestoreInstanceState() .
  • В манифесте android:configChanges=»orientation|screenSize» .

Я действительно не рекомендую использовать второй метод. Поскольку в одном из моих опытов он вызывал половину экрана устройства черным при повороте от портрета к пейзажу и наоборот.

Используя первый метод, упомянутый выше, мы можем сохранять данные при изменении ориентации или изменении конфигурации. Я знаю способ хранения любых типов данных в объекте stateInstance.

Пример. Рассмотрим случай, если вы хотите сохранить объект Json. создать класс модели с геттерами и сеттерами.

Теперь в вашей деятельности в методах onCreate и onSaveInstanceState выполните следующее. Он будет выглядеть примерно так:

Ответ 21

Вот комментарий от ответа Steve Moseley (ToolmakerSteve), который ставит все в перспективе (в целом onSaveInstanceState vs onPause, восточная стоимость и западная сага)

@VVK — Я частично не согласен. Некоторые способы выхода из приложения не запускаются onSaveInstanceState (oSIS). Это ограничивает полезность ОСШ. это стоит поддерживать, для минимальных ресурсов ОС, но если приложение хочет вернуть пользователя в состояние, в котором они находились, независимо от того, как приложение было однако, вместо этого следует использовать подход постоянного хранения. Я использую onCreate для проверки на наличие пакета, и если он отсутствует, проверьте постоянное хранилище.. Это централизует принятие решений. Я могу восстановление после сбоя или выход из кнопки «Назад» или пользовательский пункт меню «Выход» или вернуться к пользователю экрана было много дней спустя. — ИнструментарийSteve Sep 19 ’15 в 10:38

Ответ 22

а затем в onCreate() или onRestoreInstanceState()

Добавьте значения по умолчанию, если вы не хотите иметь опции

Ответ 23

Чтобы получить данные состояния активности, хранящиеся в onCreate() , сначала вам нужно сохранить данные в файле savedInstanceState, переопределив метод SaveInstanceState(Bundle savedInstanceState) .

При вызове функции destroy SaveInstanceState(Bundle savedInstanceState) вызывается метод, и там вы сохраняете данные, которые хотите сохранить. И вы получите то же самое в onCreate() , когда перезагрузка активности. (SavedInstanceState не будет пустым, поскольку вы сохранили некоторые данные в нем до того, как действие будет уничтожено)

Ответ 24

Простое решение этой проблемы — IcePick

Сначала настройте библиотеку в app/build.gradle

Теперь давайте посмотрим нижеприведенный пример, как сохранить состояние в Activity

Он работает для операций, фрагментов или любого объекта, который должен сериализовать свое состояние на Bundle (например, ViewPresenters).

Icepick также может генерировать код состояния экземпляра для пользовательских представлений:

Ответ 25

Не уверен, что мое решение осуждается или нет, но я использую связанный сервис для сохранения состояния ViewModel. Храните ли вы его в памяти в службе или сохраняете и извлекаете из базы данных SQLite, зависит от ваших требований. Это то, что делают сервисы любого типа, они предоставляют такие сервисы, как поддержание состояния приложения и абстрактную общую бизнес-логику.

Из-за ограничений памяти и обработки, присущих мобильным устройствам, я отношусь к представлениям Android аналогично веб-странице. Страница не поддерживает состояние, это просто компонент уровня представления, единственной целью которого является представление состояния приложения и принятие пользовательского ввода. В последних тенденциях в архитектуре веб-приложений используется устаревший шаблон Модель, представление, контроллер (MVC), где страница представляет собой представление, данные домена являются моделью, а контроллер располагается за веб-службой. Тот же шаблон можно использовать в Android, когда View, ну. View, модель — это данные вашего домена, а Controller реализован в виде сервиса, привязанного к Android. Всякий раз, когда вы хотите, чтобы представление взаимодействовало с контроллером, выполните привязку к нему при запуске/возобновлении и отключите при остановке/паузе.

Этот подход дает вам дополнительный бонус за соблюдение принципа разделения интересов, заключающегося в том, что бизнес-логика всех ваших приложений может быть перенесена в ваш сервис, что сокращает дублирование логики между несколькими представлениями и позволяет представлению применять другой важный принцип проектирования, Single Responsibility.

Ответ 26

Котлин

Вы должны переопределить onSaveInstanceState и onRestoreInstanceState , чтобы хранить и извлекать переменные, которые вы хотите сохранять постоянными

График жизненного цикла

Хранить переменные

Получить переменные

Ответ 27

Теперь Android предоставляет ViewModels для сохранения состояния, вы должны попытаться использовать это вместо saveInstanceState.

Ответ 28

Добавление LiveData (компоненты архитектуры Android) в ваш проект

добавить следующую зависимость

LiveData принимает наблюдателя и уведомляет его об изменениях данных, только когда он находится в состоянии STARTED или RESUMED. Преимущество LiveData заключается в том, что когда ваша деятельность переходит в любое состояние, кроме STARTED или RESUMED, она не вызывает метод onChanged для наблюдателя.

Ответ 29

Что сохранить, а что нет?

Вы когда-нибудь задумывались, почему текст в EditText автоматически сохраняется при изменении ориентации? Ну, этот ответ для вас.

Когда экземпляр Activity будет уничтожен, и система заново создаст новый экземпляр (например, изменение конфигурации). Он пытается воссоздать его, используя набор сохраненных данных старого состояния активности (состояние экземпляра).

Состояние экземпляра — это коллекция пар ключ-значение, хранящихся в объекте Bundle .

По умолчанию система сохраняет объекты View в Bundle, например.

  • Текст в EditText
  • Положение прокрутки в ListView и т.д.

Если вам нужна другая переменная для сохранения в качестве части состояния экземпляра, вы должны переопределить onSavedInstanceState(Bundle savedinstaneState) .

Например, int currentScore в GameActivity

Более подробная информация о onSavedInstanceState (Bundle saveinstaneState) при сохранении данных

Так что по ошибке, если вы забудете вызвать super.onSaveInstanceState(savedInstanceState); поведение по умолчанию не будет работать, т.е. текст в EditText не будет сохранен.

Какой выбрать для восстановления состояния активности?

Оба метода получают один и тот же объект Bundle, поэтому не имеет значения, где вы пишете логику восстановления. Единственное отличие состоит в том, что в onCreate(Bundle savedInstanceState) вы должны будете дать нулевую проверку, пока она не нужна в последнем случае. Другие ответы уже содержат фрагменты кода. Вы можете отослать их.

Подробнее о onRestoreInstanceState (Bundle saveinstaneState)

Всегда вызывайте super.onRestoreInstanceState(savedInstanceState); чтобы система по умолчанию восстановила иерархию просмотра

бонус

onSaveInstanceState(Bundle savedInstanceState) вызывается системой только тогда, когда пользователь намеревается вернуться в действие. Например, вы используете приложение X и неожиданно получаете звонок. Вы переходите в приложение вызывающего абонента и возвращаетесь в приложение X. В этом случае будет вызван метод onSaveInstanceState(Bundle savedInstanceState) .

Но учтите это, если пользователь нажимает кнопку «Назад». Предполагается, что пользователь не намерен возвращаться в Activity, поэтому в этом случае onSaveInstanceState(Bundle savedInstanceState) не будет вызываться системой. Вы должны учитывать все сценарии при сохранении данных.

Соответствующие ссылки:

Ответ 30

Вы можете использовать Live Data и View Model Для L ifecycle Handel Из JetPack . см. эту ссылку:

Источник

Оцените статью