Сообщение SingleLiveEvent, если оно вызывается несколько раз, отправляется только последнее событие (но мне нужны все события на мой взгляд)

Я использую SingleLiveEvent для передачи моей модели ViewModel и моей активности. Примерно так (псевдокод):

    class MyActivity: BaseActivity{


fun onCreate(){
//Init viewmodel and so on
 viewModel.commands.observe(this, { command ->
            logger.debug("Command received","------>>>>>>>"+command.javaClass.simpleName)
            processCommand(command)
        })

}

}

И моя ViewModel выглядит примерно так:

class MyViewModel(application: Application) : BaseAndroidViewModel(application) {

val command: SingleLiveEvent<CustomCommands> = SingleLiveEvent()

init{

loadOneThing()
command.postValue(CustomCommands.MessageCommand("one thing loaded"))

loadAnotherThing()
command.postValue(CustomCommands.MessageCommand("another thing loaded"))

}
}

Проблема, с которой я столкнулся, заключается в том, что Activity получает только последнюю команду, и это для каждого дизайна. SingleLiveEvent - это дочерний класс из LiveData, и в документации для метода postValue говорится следующее:

  • * If you called this method multiple times before a main thread executed a posted task, only * the last value would be dispatched.

Interestingly, if I set a breakpoint on the line that posts the commands, the emulator/device/main thread has time enough to process the first command, and the second command is sent too. But when executing the app without breakpoints, if the tasks that the viewmodel does between commands are done very fast (no rest requests or things like that, but some calculations), the main thread does not have time enough to finish the first command, and the second command is ignored.

Но мне действительно нужно View для получения всех событий / команд, которые отправляет ViewModel.

Я полагаю, что ни SingleLiveEvent, ни LiveData не подходят для этого варианта использования из-за проблемы повторной отправки уже использованных событий при повороте устройства и т. Д.

Кто-нибудь знает, как это сделать лучше?

Заранее спасибо!


person R. Campos    schedule 23.05.2021    source источник
comment
SingleLiveEvent не рекомендуется с 2019 г .: reddit.com/r/androiddev/comments/ dz1q3f /   -  person EpicPandaForce    schedule 24.05.2021


Ответы (1)


вы пробовали использовать EventObserver?

/**
 * Used as a wrapper for data that is exposed via a LiveData that represents an event.
 */
open class Event<out T>(private val content: T) {

    @Suppress("MemberVisibilityCanBePrivate")
    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}

/**
 * An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has
 * already been handled.
 *
 * [onEventUnhandledContent] is *only* called if the [Event]'s contents has not been handled.

*/

class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
    override fun onChanged(event: Event<T>?) {
        event?.getContentIfNotHandled()?.let {
            onEventUnhandledContent(it)
        }
    }
}

Используйте его с данными в реальном времени

val someEvent: MutableLiveData<Event<Unit>>= MutableLiveData()

когда тебе нужно какое-то мероприятие

fun someEventOccured(){
   someEvent.value = Event(Unit)
}

Фрагмент файла, наблюдение за событием

viewModel.someEvent.observe(this, EventObserver {
    //somecode
})
person Kashif Mehmood    schedule 23.05.2021