LiveData vs. MutableLiveData: Exploring Value Setting Methods in Kotlin

Jaykishan Sewak
4 min readJul 5, 2023

--

Hey friends hows going on?, few days ago I appreard for one Interview and there I was asked difference, use case and examples of Live data and MutableLive data. So in today’s article we will look around Live and MutableLive data with usecase and example.

Introduction:
In modern Android app development, the use of reactive programming and data-driven architectures has become increasingly popular. LiveData, introduced as part of the Android Architecture Components, is a powerful tool for building reactive UIs. In this article, we will explore the differences between LiveData and MutableLiveData in Kotlin and compare the two methods for setting values, namely setValue() and postValue().

LiveData:
LiveData is an observable data holder that is aware of the lifecycle of an Android component, typically used in conjunction with ViewModel. It allows data to be observed by UI components, ensuring that they are updated automatically when the underlying data changes.

LiveData provides several benefits, including automatic lifecycle management, preventing memory leaks, and maintaining UI consistency.

MutableLiveData:
MutableLiveData is a subclass of LiveData that provides mutability, allowing the modification of its value. It is commonly used within ViewModels to hold and expose data that can be updated over time. MutableLiveData extends the functionality of LiveData by adding methods to modify the stored value.

setValue():
The setValue() method is used to set the value of a MutableLiveData instance synchronously. It should be called from the main thread, as it directly updates the value and triggers observers immediately.

This method is suitable when you need to update the value and ensure that all observers are immediately notified and UI components reflect the updated data.

Example use case for setValue():
Suppose you have a weather application that displays the current temperature. The temperature data is stored in a MutableLiveData instance, and you want to update it whenever a new reading is available from a sensor. In this case, calling setValue() with the new temperature value will immediately update the UI, ensuring real-time temperature updates for the user.

postValue():
The postValue() method is used to set the value of a MutableLiveData instance asynchronously. It should be called from a background thread, as it posts the value update to the main thread’s message queue. This method ensures that the value is set on the main thread, which is essential for maintaining UI consistency.

Example use case for postValue():
Consider a chat application that receives messages in real-time. When a new message arrives, you need to update the chat screen’s UI with the received message.

Since network operations are usually performed on a background thread, using postValue() ensures that the UI update happens on the main thread, preventing concurrency issues and maintaining a smooth user experience.

Lets look at code snippet

class TemperatureViewModel : ViewModel() {
private val _temperature = MutableLiveData<Double>()
val temperature: LiveData<Double>
get() = _temperature

fun updateTemperature(newTemperature: Double) {
// Updating temperature synchronously using setValue()
_temperature.value = newTemperature
}

fun receiveMessageInBackground(newMessage: String) {
// Simulating background thread
Thread {
// Processing and receiving a new message
val processedMessage = processMessage(newMessage)

// Updating temperature asynchronously using postValue()
_temperature.postValue(processedMessage)
}.start()
}

private fun processMessage(message: String): Double {
// Simulated message processing
// Parsing and extracting temperature value from the message
// Example: "Temperature: 25.5°C"
val temperatureString = message.substringAfter("Temperature: ").substringBefore("°C")
return temperatureString.toDoubleOrNull() ?: 0.0
}
}

// Example usage in an Activity or Fragment

class WeatherActivity : AppCompatActivity() {
private lateinit var temperatureViewModel: TemperatureViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_weather)

temperatureViewModel = ViewModelProvider(this).get(TemperatureViewModel::class.java)

// Observing the temperature LiveData
temperatureViewModel.temperature.observe(this, Observer { temperature ->
updateTemperatureUI(temperature)
})

// Simulating an update in temperature
val newTemperature = 28.9
temperatureViewModel.updateTemperature(newTemperature)

// Simulating a received message in the background
val newMessage = "Temperature: 32.1°C"
temperatureViewModel.receiveMessageInBackground(newMessage)
}

private fun updateTemperatureUI(temperature: Double) {
// Update the UI with the new temperature value
textViewTemperature.text = "$temperature°C"
}
}

In this example, we have a `TemperatureViewModel` that holds a `MutableLiveData` instance called `_temperature`. The `updateTemperature()` function uses `setValue()` to synchronously update the temperature value and notify any registered observers.

The `receiveMessageInBackground()` function simulates a background thread that processes a new message, extracts the temperature value, and then updates the temperature value using `postValue()`. This ensures that the UI update happens on the main thread, even though the function is called from a background thread.

In the `WeatherActivity`, we observe the `temperature` LiveData and update the UI with the new temperature value in the `updateTemperatureUI()` function.

Conclusion:
LiveData
and MutableLiveData are valuable components in Android development, enabling the creation of reactive and responsive user interfaces. While LiveData provides an immutable data holder, MutableLiveData extends its functionality by allowing value modification.

The choice between setValue() and postValue() depends on the context and threading requirements of your application. Using setValue() is suitable when immediate UI updates are required, while postValue() is preferred for updating values asynchronously from background threads.

Understanding these differences and selecting the appropriate method based on your use case will lead to robust and efficient Android applications using Kotlin.

If you found article useful then please start following me. You can also find me on LinkedIn and GitHub.

You can find my more article on GFG portal also.

--

--

Jaykishan Sewak

Mobile Lead | Android Tech Lead at HSBC | Flutter | MVVM | JetPack Compose | kotlin | Medium blog writer | GitHub Contributor