В какой последовательности вызывается onDetachedFromWindow относительно других методов жизненного цикла View
Что проверяют
Понимаете ли вы, что жизненный цикл View привязан к окну, а не к Activity, и знаете ли, где освобождать ресурсы кастомной вьюшки. Следом часто спрашивают, может ли View после onDetachedFromWindow() снова оказаться на экране.
Как отвечать
Базовый порядок для вьюшки, созданной из XML:
- конструктор, затем
onFinishInflate()после разбора разметки; onAttachedToWindow(): вьюшка попала в окно и получилаAttachInfo. Вызывается до первого измерения;onMeasure(),onSizeChanged(),onLayout(),onDraw(): проход отрисовки,onSizeChanged()только при изменении размера. Дальше повторяется поrequestLayout()иinvalidate();onWindowVisibilityChanged()иonVisibilityChanged(): приходят по ходу жизни, например когда окно уходит в фон;onDetachedFromWindow(): вьюшку убрали из окна.
Непосредственно перед onDetachedFromWindow() система вызывает onWindowVisibilityChanged(GONE), если окно ещё не было скрыто. У ViewGroup при отсоединении сначала отрабатывают дочерние вьюшки, потом сам контейнер, при присоединении наоборот.
Относительно Activity: при её уничтожении onDetachedFromWindow() приходит после onDestroy(), потому что окно удаляется уже после колбэка.
Практика: в onAttachedToWindow() подписываются и запускают анимации, в onDetachedFromWindow() отписываются, останавливают аниматоры и отменяют корутины. Снаружи на эти события подписываются через addOnAttachStateChangeListener или doOnDetach из core-ktx, текущее состояние проверяют через isAttachedToWindow.
Где спотыкаются
Считают onDetachedFromWindow() концом жизни вьюшки и освобождают ресурсы безвозвратно. При переиспользовании вьюшек, например в RecyclerView, она может отсоединиться и снова присоединиться, и тогда всё нужно корректно поднять заново в onAttachedToWindow().
Путают видимость с отсоединением: setVisibility(GONE) не вызывает onDetachedFromWindow(), вьюшка остаётся в иерархии.
Запускают подписки и аниматоры в конструкторе и нигде их не останавливают. Они переживают экран и держат ссылку на Context, отсюда утечка.