LiveData setValue vs postValue in Android

Whenever we want some kind of communication between different classes of the same program then we can do this by using the reference of that class or you can apply any other way of doing the same. For example, below is the code for the communication between two classes Component1 and Componet2:

class Component1 {
    private val component2 = ...

    fun onDataLoaded(data : Data) {
        component2.setData(data)
    }
}

But things become harder when you are dealing with the same situation in case of Android Activity.

For example, if you are making an application that gives some random number on clicking a button, then if you rotate the Android device i.e. if you change the orientation of the screen then your generated random number will be lost and you have to regenerate it. The situation becomes more severe when you are dealing with some large data and suddenly due to any change in UI, the whole data will be lost.

The best and the recommended solution would be to use LiveData, which is a part of Android Jetpack.

So, in this blog, we will learn about LiveData and it’s two important methods i.e. setValue and postValue.

What is LiveData?

If we look at the definition of LiveData from the Android Developer Website, then it says that:

LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services.

In a simple way, LiveData is basically a data holder and it is used to observe the changes of a particular view and then update the corresponding change.

So, LiveData is used to make the task of implementing ViewModel easier. The best part about LiveData is that the data will not be updated when your View is in the background.

So, the question that arises here is that how does our LiveData in the ViewModel update the Activity? In order to use LiveData in our Activity along with the ViewModel, after registering the Observer in the Activity, we need to override the onChange() method and this onChange() method will be called when we have to data of the view using the LiveData.

LiveData notifies the observer by using the setValue() and postValue() methods. Following are the steps that can be followed to use LiveData in our application:

  • Create LiveData objects: You can think of LiveData as a DataType that is used to notify the observer whenever there is a change in the value of the data. So, our first task should be to create an object of LiveData in your ViewModel class:
class NameViewModel : ViewModel() {

    // Create a LiveData with a String
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    // Rest of the ViewModel...
}
  • Observe LiveData objects: Our next step is to observe the LiveData for any changes and the best place to do so is in onCreate() method. So, in general, we can say that LiveData notifies the update only when the data is changed and also, only to the active observers. Following is the code for observing the LiveData in your Main Activity:
class NameActivity : AppCompatActivity() {

    private lateinit var model: NameViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Other code to setup the activity...

        // Get the ViewModel.
        model = ViewModelProviders.of(this).get(NameViewModel::class.java)


        // Create the observer which updates the UI.
        val nameObserver = Observer<String> { newName ->
            // Update the UI, in this case, a TextView.
            nameTextView.text = newName
        }

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.currentName.observe(this, nameObserver)
    }
}
  • Update LiveData Objects: Our last step should be to update the objects of the LiveData. Here, you can either use the setValue() method or the postValue() method of the MutableLiveData class. The reason behind using the MutableLiveData class is that the LiveData has no public methods for updating the stored value so, we use MutableLiveData class. Here is the code for updating the value of the object of the LiveData.
button.setOnClickListener {
    val anotherName = "John Doe"
    model.currentName.setValue(anotherName)
}

Difference between setValue() and postValue()

In the last section of the blog, we saw how to use LiveData in our project. So, one question that comes in mind is why is there a need for two methods setValue() and postValue() for the same functionality? Let’s find out.

Let’s take an example, suppose you want to update some value using the LiveData. Either you can update the data on the Main thread or you can update the data using the background thread. While using the Main thread to change the data, you should use the setValue() method of the MutableLiveData class and while using the background thread to change the LiveData, you should use the postValue() method of the MutableLiveData class.

So, the duty of the postValue() method is to post or add a task to the main thread of the application whenever there is a change in the value. And the value will be updated whenever the main thread will be executed.

While the setValue() method is used to set the changed value i.e. the change value will be dispatched to the active observer of the application. This setValue() method must be called from the main thread.

Let’s take an example, where both the setValue() and postValue() methods are used:

liveData.postValue("a")
liveData.setValue("b")

Since we use setValue() method from the main thread to set the value, so the value “b” will be set first and after that, the main thread will change the value to “a” from “b”. This is because the postValue() method is to post the changes to the main thread and this change will be applied once the main thread will be executed. So, the value will be overridden by “a”.

Another thing that should be noted here is that if you are calling the postValue() method a number of times before the execution of the main thread, then the value that is last passed will be dispatched to the main thread and rest of the values will be discarded.

Conclusion

In this blog, we learned how to use LiveData to implement the concept of ViewModel in our project. LiveData is used to notify the user if there is a change in the value of objects of LiveData. For this purpose, we use two methods i.e. setValue() and postValue(). We also learned about these two methods. So, I hope you enjoyed this blog. For more information about ViewModels, you can read our blog on ViewModel.

Keep Learning :)

Team MindOrks!