Search code examples
androidandroid-livedataandroid-viewmodelandroid-mvvm

Android LiveData event sequence guarantees?


I have the following code in my Fragment, subscribing to my ViewModel's LiveData events.

    viewModel.successfullyAddedEvent.observeEvent(this){
        // do result handling by shared view model to the calling fragment
        result.successfullyAddedEvent.postValue(Event(it))
        findNavController().navigateUp()
    }

    viewModel.successfullyEditedEvent.observeEvent(this){
        // do result handling by shared view model to the calling fragment
        result.successfullyEditedEvent.postValue(Event(it))
        findNavController().navigateUp()
    }

    viewModel.exitRequestedEvent.observeEvent(this){
        when(it){
            ExitReason.GetDetailsFailed -> {
                Toast.makeText(context, R.string.details_load_error, LENGTH_SHORT).show()
            }
            ExitReason.UserCanceled -> { /* happy path */ }
        }

        findNavController().navigateUp()
    }

I have three places in this code where I'm calling navigateUp and I'd like to unify the navigation a bit.

It seems like it would be a code improvement to emit an ExitRequestedEvent from each case (successful add, successful edit, error case, user cancellation) and remove calls to navigateUp from those events, but I'm not sure about guarantees on receipt order. That is, if I was to post values for a successfullyAddedEvent and then an exitRequestedEvent in my viewmodel like so:

// yay my thing happened successfully, emit events
successfullyAddedEvent.postValue(Event(contentAdded))
exitRequestedEvent.postValue(Event(ExitReason.AddSuccessful))

can I be guaranteed that I'll handle the add event (which sets the result on the shared result ViewModel) before I exit this fragment, so that the calling fragment always has a result?


Solution

  • According to the documentation, postValue just means posting the task to main thread if you are not on it, so unless you have setValue somewhere in your code as well, the order should be guaranteed.

    If you want to absolutely guarantee the order (even though not necessary), you can use setValue() for that, but you have to make sure it happens on the main thread.