EventLiveData (“SingleLiveData with multiple observers”)

Darko Martinović
2 min readJan 9, 2020

LiveData is amazing android architectural component for most of use cases where we need to fetch data from some data source. Problem comes when you need to use LiveData to observe events that are consumed only once (eg. button click ).

Problem :

Lets say you have list of fruits shown in FruitsFragment, clicking on one of the elements of that list it calls method on your FruitViewModel that sets its LiveData.

FruitViewModel

In FruitsFragment you observe fruitsLiveData so you can start FruitDetail fragment once user picks his fruit.

FruitsFragment

So far so good. User picks his item from list and FruitDetail fragment opens containing fruit description.

But what happens when he presses back?

Because your FruitsFragment is on backstack it never reached DESTROYED state which means its ViewModel is still alive with its fruitsLiveData still holding Fruit object! FruitsFragment view get re-attached and onActivityCreated is called again creating new observer which gets triggered right away.

You can never go back to your fruits!

Bonus problem: Because we created new Observer in onActivityCreated our view model now holds 2 observers!

Solutions so far:

Been reading a lot about this problem so far I found 3 solutions, all 3 come with some problems of their own.

SingleLiveEvent described in this article is limited to one observer, as well as Event Wrapper described here.

Maybe most interesting solutions is SingleLiveEvent (LiveData) with multi observers described here, but all observers are tied to the life-cycle of the first owner that calls observe() method .

My solution:

All observers will only receive events once they happen!

Usage:

First add lib to your apps gradle build file:

implementation 'com.rugovit.eventlivedata:eventlivedata:1.0'

Next use it just as you would regular live data:

Multiple observers receive events.

In case of same multiple observer problem(fragment back-stack) it is possible to use observeInOnStart() method. Which limits life of the observer between State.STARTED and Event.ON_STOP, allowing EventLiveData to remove Observer when owner hits ON_STOP.

Observing in limited life-cycle range.

It is possible to define custom range for each observer with observe( LifecycleOwner, Observer ,State,Event) method.

Custom limitation of life-cycle range.

Check out my GitHub repository with lib implementation , documentation and example app:

If you like this and find it helpful give me a clap!

--

--