LiveData: Android
LiveData: Android
19 March 2021
LiveData is one of the first architectural components. It is a simple lifecycle-aware observable data holder.
Dependency: implementation “androidx.lifecycle:lifecycle-livedata:$lifecycle_version”
As we already know, activities or fragments have their own lifecycles and LiveData is bound to them. And it acts as a data holder for us. Let’s start with observable:
What is an observable?
- In our object oriented world, likely the most straightforward way of communicating one component and another is by having a reference from one protest to another, and fair call it directly.
- In any case, in android this might have a few issues. As we all know, components in android have distinctive life cycles and diverse lifespans.
- As I anticipate you could be recognizable with ViewModel. A straightforward thing like gadget turn can really reproduce the action.
- So, you likely know that having a reference within the ViewModel would be a terrible thought. Since it leads to memory spills and indeed crashes and will invalid pointer exceptions.
- So rather than having a reference to the movement within the ViewModel, we are getting to attempt to have the reference of the ViewModel within the action. So how do we communicate, how do we send information from the ViewModel to the activity.
- Well, rather than doing that, we are planning to let the action watch the ViewModel. And for that we are aiming to utilize perceptible LiveData.
- Let’s get started:
public class LocationViewModel extends ViewModel { // Create a LiveData with a String private MutableLiveData<String> mCurrentLocation; public LiveData<String> getCurrentLocation() { if (mCurrentLocation == null) { mCurrentLocation = new MutableLiveData<>(); } return mCurrentLocation; } // Rest of the ViewModel... }
- Clearly, we can see that LiveData is immutable. It is not possible to update it directly. So we will use the MutableLiveData to update the data. There are two public methods available here:
- setValue(T) – It is used when executing on the main thread.
- postValue(T) – It is used when executing on the background thread.
public class LocationActivity extends AppCompatActivity { private LocationViewModel model; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(this).get(LocationViewModel.class); // Create the observer which updates the UI. final Observer<String> locationObserver = new Observer<String>() { @Override public void onChanged(@Nullable final String newLocation) { // Update the UI, in this case, a TextView. locationTextView.setText(newLocation); } }; /* Observe the LiveData, passing in this activity as the LifecycleOwner and the observer. */ model.getCurrentLocation().observe(this, locationObserver); } }
- The observe() method used to observe the changes in the data. It takes params one is corresponding lifecycle owner (activity or fragment) and locationObserver(the observer of a particular object) which invokes onChanged after data changed in ViewModel.
- There may be multiple objects that have the observers.
MediatorLiveData
MediatorLiveData is a child class of LiveData that allows us to combine a number of LiveData sources. MediatorLiveData objects listen to the change of parent LiveData item changes.
For instance, on the off chance that you have a LiveData object in your UI that can be refreshed from data changes that may occur by various sources.
A LiveData object related with the information put away in the standard storage.
A LiveData object related with the information got to from the web server.
Your movement just needs to watch the MediatorLiveData object to get refreshes from the two sources.
Transformations
Transformations is an operation that takes place before the observer notifies. Consider the database has LiveData which is present in the ViewModel then it becomes the life cycle owner. That is practically not possible. The owner must be an activity or a fragment. Then comes the Transformations.switchMap comes to the scene to do the things for us. They are two type of transformations available:
- Transformations.map()
- Takes a LiveData value and returns a LiveData value.
LiveData<Student> studentLiveData= ...; LiveData<String> StudentName = Transformations.map(studentLiveData, student-> { student.name + " " + student.lastName });
- Takes a LiveData value and returns a LiveData value.
- Transformation.switchMap()
- It is similar to the map() but the only change is it unwraps the data before passing to the downstream.
private LiveData<Student> getStudent(String rollNo) { ...; } LiveData<String> studentNo = ...; LiveData<Student> student= Transformations.switchMap(studentNo, rollNo -> getStudent(rollNo) );
- It is similar to the map() but the only change is it unwraps the data before passing to the downstream.
Custom LiveData
It is also possible to create a custom LiveData just by extending it and implementing the respective methods. Here the list of things to note are;
- onActive()
- onInActive()
- setValue() and postValue()
onActive(), we will perform the registering task. Similarly, unregisters have to take place in onInActive(). The setValue() and postValue() is to inform the users about the updated data.
Not To Use:
- If there are a lot of operators, it is better to use RX.
- And if there is nothing to do with the lifecycle or with the user interface, there is no need to use the LiveData. We just can use the callback interfaces.