Android: How to Fix a Serious Problem in LiveData

Avoid observing the same data whenever component life-cycle changes

Siva Ganesh Kantamani
Jan 23 · 2 min read
Photo by Arnold Francisca on Unsplash

Introduction

LiveData is from the JetPack family. It’s mostly used to deliver data from the view model to fragments and activities in the latest architectures, like MVVM and clean.

LiveData is an observable data holder class. Unlike other data holders, LiveData is a life cycle aware of respective components like Activities, Fragments, services, and more. As it is a life cycle aware, LiveData makes sure that it only publishes the data to those who are observing it when they are active, which means when they’re in the foreground.

Problem

LiveData publishes the data to the destination component if it is in the foreground. If it’s not, it might hold the data and deliver it when that specific component comes back to the foreground, like in onResume state.

Now that we know how it works, let’s say we have a livedata with multiple observers and three fragments — F1, F2, and F3 — which are in the stack. All three fragments share a ViewModel and observe a liveData of type T to show a message.

Now, when we post data of type T through liveData, because fragment F3 is in the foreground the message is shown first in F3. That’s good — but what happens when we click back? Fragment F2 is resumed, as F2 is one of its subscribers. LiveData delivers the data again, so the message is shown twice and the same repeats with fragment F1.

This is how livedata works but, in real-time, there might be cases where once the data is observed, it shouldn’t be observed again. The following section contains the solution.

Solution

Step 1

First, we need to create a class with the name Event to wrap the data that the livedata is exposing. Have a look at how to create an Event class:

In this class, we maintain a flag hasBeenHandled to check whether the data is observed at least once.

Step 2

Now we need to create another class with name EventObserver that extends Observer. Just to make the process of using it simple, have a look:

When new data is posted, the onChanged function is triggered and the flag hasBeenHandled is set to false. As soon as the first subscriber observed the data, the flag hasBeenHandled will be true, so that the rest of the subscribers won’t receive the data and the cycle repeats every time new data is posted.

Step 3

While observing livedata, we need to use EventObserver instead of regular Observer so that handling is simplified. Have a look:

This is the solution I’ve found from 2020 AndroidDev summit app source code.

Thank you for reading.

Better Programming

Advice for programmers.

Siva Ganesh Kantamani

Written by

Learn. Code. Write. Repeat. Visit me at https://about.me/sivaganesh_kantamani & Join my email list at https://tinyletter.com/Siva_Ganesh_Kantamani

Better Programming

Advice for programmers.

More From Medium

More from Better Programming

More from Better Programming

More from Better Programming

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade