Bakken & Baeck logo

Introducing SingleLiveEvent | Colin Dodd

One of the nice things about LiveData being lifecycle aware is that you don't need to worry about Views having the latest data from the ViewModel; even after rotate! Sometimes however, that can cause unforeseen issues.

When an Android device is rotated, the View is killed and created again. At that point it is up to the developer to ensure that data is not lost during rotation. If you use LiveData this problem goes away; when the View is recreated it connects to the same LiveData and the previously cached results are returned to the View.

Consider a simple example, where clicking a Button causes an action to happen in the ViewModel. The action can succeed or fail. The View observes a LiveData that broadcasts the success state of the action.

A failure state

In this example, after the action is triggered it fails for some reason. The ViewModel sends out the failure state, and the View which is observing changes receives this failure state. The View decides to handle this failure state by showing a Toast.

So far, so good - there doesn't seem to be an issue. However, what happens when the device is rotated?

The LiveData rotation bug

🙈

Now every time we rotate the device, the Toast is shown! When the View is recreated, it attaches to the ViewModel, which broadcasts the cached LiveData failure state. As long as we keep rotating the device the toast will keep showing.

SingleLiveEvent to the rescue

In this instance, what we want instead is a LiveData that can only be observed once. No caching, once the value is observed it is gone forever. This is exactly what SingleLiveEvent does. It will only broadcast new values to new subscribers. In practice this means it is useful in situations where you don't want LiveData such as the example above.

It also handles the situation where there are multiple subscribers. Each subscriber will get the event once. It is only new subscribers that are affected.

SingleLiveEvent is not part of Android Architecture Components, but it is part of the official Architecture Components sample code. Google I/O 2018 is approaching so it will be interesting to see what will happen with the Arch framework.