LifecycleOwner: разница между Fragment (self) и Fragment # viewLifecycle - PullRequest
0 голосов
/ 01 ноября 2019

Использование Android X и Android Architecture Components, а именно: ...

  • Навигация
  • Жизненный цикл
  • ViewModel

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

При использовании ViewModel, предоставляющего LiveData s для Fragment, в настоящее время существует два LifecycleOwners , который можно использовать для oberve :

  1. самого Fragment или
  2. свойства Fragment mViewLifecycleOwner.

До сих пор я всегда и исключительно использую Fragment для всех без исключения LiveData, выставленных ViewModel с.

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

  • навигационная версия ktx 2.2.0-rc01;
  • активность ktx версия 1.1.0-rc01;
  • фрагмент версии ktx 1.2.0-rc01;
  • версия жизненного цикла ktx 2.2.0-rc01;

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

Это привело к тому, что меня предупредили по старому java-коду:

enter image description here

Почему это так? на самом деле два LifecycleOwners ?

Должен ли я также следовать этому предупреждению при настройке владельца жизненного цикла макета с привязкой к данным фрагмента (используя библиотеку Databinding)?

Тогда что такоеиспользовать для самого фрагмента как LifecycleOwener?

1 Ответ

3 голосов
/ 01 ноября 2019

Существует два разных жизненных цикла, потому что сам фрагмент живет дольше, чем вид фрагмента.

Существует ряд событий, которые могут привести к разрушению вида фрагмента, но в настоящее время он поддерживает сам фрагмент:

  1. Помещение фрагмента в задний стек (т. Е. Когда вы navigate() переходите к другому фрагменту)
  2. Вызов detach() во фрагмент
  3. Вызов setMaxLifecycle(Lifecycle.State.CREATED)на фрагменте

В этих случаях представление фрагмента разрушается, перемещая жизненный цикл представления фрагмента на DESTROYED. Однако сам жизненный цикл фрагмента не разрушен - обычно он остается как CREATED. Это означает, что фрагмент может проходить через несколько циклов onCreateView() -> onViewCreated() -> onDestroyView(), проходя только один раз onCreate().

Когда это становится проблемой, возникает вопрос о том, какLiveData работает. Когда вы observe a LiveData, LiveData автоматически отменяет регистрацию наблюдателя, когда жизненный цикл достигает DESTROYED. Но если вы используете жизненный цикл фрагмента до observe в onCreateView() и т. Д., Этот зарегистрированный наблюдатель все еще будет существовать после onDestroyView(), несмотря на уничтожение вида. Это означает, что во второй раз, когда ваш фрагмент проходит через onCreateView(), вы фактически создадите второго активного наблюдателя, причем оба будут работать одновременно. Затем три наблюдателя в следующий раз и снова включите.

Используя представление LifecycleOwner в onCreateView() / onViewCreated(), вы гарантируете, что одновременно будет работать только один активный наблюдатель, и что наблюдатели связанык предыдущему представлению экземпляры корректно уничтожаются вместе с представлением. Таким образом, да, вы всегда должны использовать getViewLifecycleOwner() в качестве LifecycleOwner, когда находитесь в onCreateView() или onViewCreated(), в том числе при использовании привязки данных.

Конечно, если вы регистрируетесьОбозреватель в onCreate(), тогда представление LifecycleOwner еще не существует (оно создано прямо перед onCreateView()), и у вас нет проблемы множественной регистрации, поэтому проверка Lint специально не применяется к выполненным регистрациям. в onCreate() время. В этих случаях использование самого жизненного цикла Фрагмента абсолютно правильно.

Согласно Фрагментам: прошлое, настоящее и будущее , одно из будущих улучшений для Фрагментов будет объединять дважизненные циклы вместе, всегда уничтожая Фрагмент всякий раз, когда вид Фрагмента разрушен. Это еще не доступно ни в одной поставленной версии Фрагментов, альфа или иным образом.

...