Чем Lifecycle компоненты в Jetpack лучше колбеков в Activity
Что проверяют
Понимаете ли вы, что проблема не в самих колбеках, а в том, что Activity превращается в свалку: каждый новый объект добавляет пару строк в onStart и onStop, и однажды строку в onStop забывают. Библиотека жизненного цикла переворачивает эту зависимость, и от вас ждут объяснения именно этого, а не списка достоинств.
Как отвечать
В классической схеме экран знает про всех, кому нужны события жизненного цикла, и раздаёт их вручную. С Lifecycle у владельца (Activity, фрагмент, а у фрагмента отдельно viewLifecycleOwner для его представления) есть объект жизненного цикла, и потребитель подписывается сам:
class LocationTracker(lifecycle: Lifecycle) : DefaultLifecycleObserver {
init { lifecycle.addObserver(this) }
override fun onStart(owner: LifecycleOwner) { startUpdates() }
override fun onStop(owner: LifecycleOwner) { stopUpdates() }
}Что это даёт по сути:
- экран ничего не знает о трекере, и удаление фичи не оставляет забытой строки в колбеке;
- состояние можно спросить, а не угадывать по самодельному флагу:
lifecycle.currentState.isAtLeast(STARTED); - порядок событий гарантирован, в том числе для наблюдателя, добавленного позже;
- поверх этого работает остальной
Jetpack:LiveDataдоставляет значение только активному наблюдателю и отписывается сама,lifecycleScopeотменяет корутины,repeatOnLifecycleостанавливает сбор потока у невидимого экрана.
Честно добавьте, что колбеки никуда не делись, вся конструкция построена на них.
Где спотыкаются
Говорят, что Lifecycle сам освобождает ресурсы. Он только присылает событие, а отписку пишете вы или библиотека. Анонимный слушатель со ссылкой на экран остаётся утечкой ровно как раньше.
Во фрагменте подписываются на this вместо viewLifecycleOwner. Представление фрагмента умирает раньше самого фрагмента, и после возврата по стеку наблюдателей становится двое, а обновление прилетает дважды.
Собирают поток в lifecycleScope.launch без repeatOnLifecycle. Корутина живёт до уничтожения экрана, поэтому свёрнутое приложение продолжает держать подписку и обновлять невидимый интерфейс.