Live Data

Live Data

What is Live Data?

  • LiveData is an observable data holder class.
  • It is designed to observe and react to changes in data, particularly data that is part of the user interface (UI).
  • LiveData follows the observer pattern, allowing components such as activities, fragments, and services to observe changes in the data and update the UI accordingly.

Why do we need LiveData?

LiveData works well in resolving mainly two issues:
  • It removes the leaks caused by the interfaces/callbacks that send results to the UI thread. This is a core feature of an MVVM model where callbacks are sent from ViewModel to activity/fragment.
  • It de-couples tight integration between data, mediator, and the UI layers.
Let’s take the case of an application that’s developed in an MVP pattern. If we want to update the UI based on a network call response, we can call a method from the View layer to the Presentation layer to perform a network request and write the AsyncTask to do the work. Consequently, we can use the Interface to communicate this response to the Main thread for updating the UI.
notion image

Types in LiveData

There are subclasses in LiveData that are useful for their properties when updating the UI.
  1. LiveData
  1. MutableLiveData
  1. MediatorLiveData
LiveData is immutable by default. By using LiveData we can only observe the data and cannot set the data.
MutableLiveData is mutable and is a subclass of LiveData. In MutableLiveData we can observe and set the values using postValue() and setValue() methods (the former being thread-safe) so that we can dispatch values to any live or active observers.
MediatorLiveData can observe other LiveData objects such as sources and react to their onChange() events. MediatorLiveData will give us control over when we want to perform an action in particular or when we want to propagate an event.

Advantages of using LiveData

  • Ensures your UI matches your data state.
  • No memory leaks.
  • No crashes due to stopped activities.
  • No more manual lifecycle handling.
  • Always up to date data.
  • Proper configuration changes.
 

Dependency

// Old Style dependencies // 1. for Live Data implementation ("androidx.lifecycle:lifecycle-livedata-ktx:2.2.0") // 2. fro ViewModel implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0") // New Style Dependencies // View Model Dependency implementation(libs.androidx.lifecycle.viewmodel.ktx) // Live Data implementation (libs.androidx.lifecycle.livedata.ktx)

Create LiveData Objects

LiveData is a wrapper that works with various types of data, including collections like List. It is commonly used with ViewModel to easily access the data through a getter method.
class UserViewModel: ViewModel() { // Create a LiveData with a String val currentName: MutableLiveData<String> by lazy { MutableLiveData<String>() }

Work with LiveData objects

Follow these steps to work with LiveData objects:
  1. Create an instance of LiveData to hold a certain type of data. This is usually done within your ViewModel class.
  1. Create an Observer object that defines the onChanged() method, which controls what happens when the LiveData object's held data changes. You usually create an Observer object in a UI controller, such as an activity or fragment.
  1. Attach the Observer object to the LiveData object using the observe() method. The observe() method takes a LifecycleOwner object. This subscribes the Observer object to the LiveData object so that it is notified of changes. You usually attach the Observer object in a UI controller, such as an activity or fragment.
When you update the value stored in the LiveData object, it triggers all registered observers as long as the attached LifecycleOwner is in the active state.
LiveData allows UI controller observers to subscribe to updates. When the data held by the LiveData object changes, the UI automatically updates in response.

Observe LiveData Objects

  • onCreate() is the best place to start observing LiveData for the following reasons:
  1. To ensure the system doesn’t make redundant calls from an activity or fragment’s onResume() method.
  1. To ensure that the activity or fragment has data that it can display as soon as it becomes active.
  • LiveData generally updates only when data changes, and only to active observers.
class MainActivity : AppCompatActivity ) { private val viewmodel: UserViewModel by viewModels() override fun onCreate( savedInstanceState: Bundle?) { Super. onCreate( savedInstanceState) // 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 viewmodel. currentName.observe(this, name@bserver) } }
  • When observe() is called with the nameObserver parameter, the onChanged() method is triggered right away, passing the latest value stored in currentName. If no value has been set in currentName by the LiveData object, onChanged() will not be called.

Update LiveData Objects

  • LiveData has no publicly available methods to update the stored data.
  • The MutableLiveData class exposes the setValue(T) and postValue(T) methods publicly and you must use these if you need to edit the value stored in a LiveData object.
  • Usually MutableLiveData is used in the ViewModel and then the ViewModel only exposes immutable LiveData objects to the observers.
private val _factsLiveData = MutableLiveData<String>( "Text") val factsLiveData: LiveData<String> = _factsLiveData
button.setOnClickListener { val anotherName - "John Doe" viewmodel. currentName. setValue( anotherName ) }
Note: You must call the setValue(T) method to update the LiveData object from the main thread. If the code is executed in a worker thread, you can use the postValue(T) method instead to update the LiveData object.

What is the difference between livedata and MutableLiveData?

  • LiveData, We can only observe the data with LiveData and cannot change it.
  • LiveData is immutable, MutableLiveData is mutable & thread-safe. So yes, the difference comes only by making postValue and setValue public.
  • MutableLiveData is a subclass of LiveData that is mutable.
  • MutableLiveData, we can observe and set values using the postValue() and setValue() methods (the former of which is thread-safe), allowing us to send values to any live or active observers.
  • setValue() runs on the main thread.
  • postValue() runs on the background thread.