Какие возможности открываются с диспозером эффекта при привязке сайд эффекта к жизненному циклу в Jetpack Compose
Что проверяют
Понимаете ли вы, как в Compose живут побочные эффекты и чем выход из композиции отличается от событий жизненного цикла экрана. Следом обычно спрашивают, чем DisposableEffect отличается от LaunchedEffect и зачем нужен rememberUpdatedState.
Как отвечать
DisposableEffect(key1, ...) запускает блок, когда composable входит в композицию, и обязан вернуть onDispose { }, иначе код не скомпилируется. onDispose вызывается в двух случаях: composable ушёл из композиции или изменился ключ. Во втором случае сначала отрабатывает старая очистка, потом новый эффект. Что это открывает:
- парные операции без утечек: подписка и отписка слушателя,
BroadcastReceiver, датчики, колбэки сторонних SDK; - привязку к жизненному циклу владельца: в эффекте добавляют
LifecycleEventObserverкLocalLifecycleOwner.current.lifecycle, реагируют наON_STARTиON_STOP, а вonDisposeснимают наблюдатель; - перезапуск по данным: ключом становится
userIdилиlifecycleOwner, и при смене подписка пересоздаётся сама; - системные колбэки:
OnBackPressedCallbackв диспетчере активности, слушатели клавиатуры и конфигурации.
Лямбду из параметров внутри эффекта оборачивают в rememberUpdatedState, чтобы эффект видел свежее значение без перезапуска. Для типового случая с жизненным циклом в lifecycle-runtime-compose есть готовые LifecycleStartEffect и LifecycleResumeEffect.
Соседи по семейству: LaunchedEffect запускает корутину и сам отменяет её, SideEffect выполняется после каждой успешной рекомпозиции, а DisposableEffect нужен там, где ресурс требует явного освобождения.
Где спотыкаются
Ставят ключ Unit, хотя эффект зависит от параметра или lifecycleOwner. Подписка остаётся на старом объекте, и экран работает с устаревшими данными.
Путают выход из композиции с остановкой экрана. Когда приложение уходит в фон, композиция остаётся, onDispose не вызывается, и слушатель геолокации продолжает работать; для этого нужен наблюдатель жизненного цикла.
Приписывают DisposableEffect ускорение рендера и меньше рекомпозиций. Он про освобождение ресурсов, а на производительность влияет лишь тем, что не даёт утечь памяти.