onSaveInstanceState вызывается после onDestroyView - PullRequest
0 голосов
/ 14 мая 2018

Я имею дело со странным поведением жизненного цикла фрагмента.

У меня есть действие, содержащее два фрагмента: CityFragment - для отображения списка городов и WeatherFragment - для отображения прогноза погоды для выбранного города.

При запуске приложения на экране отображается CityFragment, когда пользователь выбирает город - WeatherFragment добавляется через supportFragmentManager с backstack.Затем, если пользователь хочет повернуть экран, я получаю ситуацию на картинке enter image description here

  • 0-2 - CitiesFragment запущен
  • 3-7 - Пользователь выбирает город, и на экране отображается WeatherFragment
  • 8-18 - поворот экрана

Как видно из журналов, сразу после выбора города пользователемonStop и onDestroyView вызываются для CitiesFragment, фрагментный вид после того, как это будет нулевым.Но когда экран поворачивается, вызывается CitiesFragment onSaveInstanceState (когда представление уже уничтожено).

Проблема здесь заключается в том, что после преобразования кода в kotlin и использования синтетического для доступа к представлению я получаю исключение NullPointerException в onSaveInstanceState, когдаЯ хочу сохранить первый видимый элемент recyclerview для восстановления после

val firstVisiblePosition = (recycler_view_cities.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()

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

  • Вопрос 1. Разве нельзя вызывать состояние onSaveInstance для CitiesFragment перед onStop и onDestroyView?
  • Вопрос 2. Как справиться с такой ситуацией?

1 Ответ

0 голосов
/ 14 мая 2018

Разве не вызывать onSaveInstanceState для CitiesFragment перед onStop и onDestroyView?

Не обязательно. Из фрагмента документов за onSaveInstanceState():

Это соответствует {@link Activity # onSaveInstanceState (Bundle) Activity.onSaveInstanceState (Bundle)} и большая часть обсуждения там относится и здесь. Обратите внимание: этот метод может быть вызван в любое время до onDestroy () . Есть много ситуаций где фрагмент может быть в основном разрушен (например, когда задний стек с без пользовательского интерфейса, показывающего ), но его состояние не будет сохранено до его собственное действие фактически должно спасти его состояние.

onSaveInstanceState() будет вызван действием, когда оно выключается (кроме случаев, когда оно явно закрыто пользователем). Ваш фрагмент получает обратный вызов, но может быть в любом состоянии до onDestroy, что означает, что пользовательский интерфейс уже может быть разрушен.

как справиться с такой ситуацией?

Проверьте, существует ли пользовательский интерфейс в onSaveInstanceState():

if (fragment.getView() != null) {
   // Your stuff
}
...