Какие знаешь способы организовать Single Event через ViewModel

«Какие знаешь способы организовать Single Event через ViewModel» — вопрос из категории Архитектура, который задают на 23% собеседований Android Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

LiveData с SingleEvent оберткой – самый популярный способ. Используем Event класс-обертку:

class Event<out T>(private val content: T) {
    private var hasBeenHandled = false

    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) null 
        else {
            hasBeenHandled = true
            content
        }
    }
}

// В ViewModel
private val _event = MutableLiveData<Event<String>>()
val event: LiveData<Event<String>> = _event

fun triggerEvent() {
    _event.value = Event("Message")
}

// Во Fragment
viewModel.event.observe(viewLifecycleOwner) { event ->
    event.getContentIfNotHandled()?.let { message ->
        showToast(message)
    }
}

Альтернативы:

  1. SharedFlow с replay=0 (одноразовые события)
  2. Channels (устаревший способ)
  3. RxJava Single/Completable

Главное преимущество Event-обертки – гарантия однократной обработки события даже при смене конфигурации.