Single live data android
LiveData is an observable data holder class that is also lifecycle aware.
Let’s take a look at an example. You’re going to have your UI, and then you’re also going to have this LiveData object, which holds some data that you want to show on screen. The UI observes the LiveData object. This is like saying the UI wants to be notified of updates. Therefore, when the LiveData changes, the UI will get notified, and then the UI can redraw itself with the new data.
So in short, LiveData makes it easy to keep what’s going on screen in sync with the data.
OK, so here’s some actual code.LiveData objects will usually be kept in the ViewModel class.
Let’s say you’re creating an activity and ViewModel for a user profile. You’ll have this user LiveData object that holds a User object.
Now, over in your activity’s onCreate, you’ll get that LiveData from the ViewModel class. Call observe on the LiveData. For the first argument, you’re going to pass in the UI, in this case the activity. The second argument is an «observer,»which is just a callback. Here you will call the code to update the UI.
Now you can change the LiveData by calling either
Use setValue if you’re running on the UI thread, and then use postValue if you’re running on a background thread. When either setValue or postValue is called,the LiveData notifies active observers.
If you’re using Android Studio 3.1 or higher, LiveData and ViewModels work with Databinding.Usually you’re going to go ahead and bind your View Model to your XML layout.
Now, after associating your ViewModel and Databinding layout, you just need to add this single line change to have your LiveData be properly observedwhen bound to the XML. You can now include references in your XML to your ViewModel and the LiveData stored with it. If you use Databinding, you’re going to no longer need to actually manually set up these observers.
So instead of creating this LiveData observer code that I showed you before, you could remove all that boilerplate. Instead, the TextView’s XML references the LiveData directly.
What makes LiveData different from other observables is that it is also lifecycle aware. This means that it understands whether your UI is on screen, offscreen or destroyed.
LiveData knows about your UI state because you passed it when you call Observe.OK, so here’s some benefits of LiveData’s life cycle awareness.
So let’s say your activity is not on screen, then your LiveData doesn’t trigger useless UI updates. If the activity or UI gets destroyed,then the observation connection is cleaned up automatically by LiveData. Thus you’ll never accidentally trigger an activity or fragment that is offscreen or destroyed to redraw itself. This is possible in part because of interfaces and classes in the Lifecycle library that are also used by framework classes.
These classes are—
Lifecycle : which is an object that represents an Android lifecycle and what state it’s in.
LifecycleOwner : which is an interface for objects that have a lifecycle like AppCompatActivity or an activity fragment;
and finally, LifecycleObserver : which is an interface for observing a lifecycle.
OK, so LiveData is a lifecycle observer. It abstracts away the need for you to deal directly with activity or factored lifecycle. So those are the basics of working with LiveData and why it’s useful.
I’m going to touch on a few more complex usages.
Room is built to work well with LiveData. Room can return LiveData objects which are automatically notified when the database data changes and have their data loaded in a background thread.This makes it easy to have the UI update when your database updates.
LiveData also provides transformations, including map, switchMap and a class called MediatorLiveData for your own custom transformations.
When do you need Map ?
We already know that LiveData’s great communicator between View and a ViewModel. What if we have a third component, maybe a repository exposing live data, How do we communicate from the ViewModel and respository? We don’t have a lifecycle in respository.
How do we make a bridge between the view and respository ?
Answer is we use a Map. A one-to-one static transformation.
This is how the signature would look like in Kotlin
The first parameter is the source, the LiveData source and the second parameter is the transformation function. It’s converting from the data of the model to the UI model. It has source, which is a LiveData of X and it returns a LiveData y. So, it’s a breach of LiveDatas and in the middle, we have a transformation function that transtorms from X to Y.
So, when you establish the transformation, the key, here, is the lifecycle is carried over for you.
SwitchMap function transformation is a lot like map, but for mapping functions that emit LiveData instead of values.So an example here is if you have a bunch of users, perhaps stored in a Room database, you might have a lookup function for those users.Using switchMap, you’d have a LiveData for the user ID. Whenever the ID changes, your user lookup function would be called with that ID. The result LiveData now references the newly found user LiveData.
OK, so no matter how many different times you call this look up function and get a different LiveData, your UI only needs to observe the result LiveData once, which is the power of switchMap.
To understand more, Let’s say we’re looking for the username «Alice». The repository is creating a new instance of that User LiveData class and after that, we display the users. After some time we need to look for the username «Bob» there’s the repository creates a new instance of LiveData and our UI subscribes to that LiveData. So at this moment, our UI subscribes to two instances of LiveData because we never remove the previous one. So it means whenever our repository changes the user’s data it sends two times subscription.
what we actually need is a mechanism that allows us to stop observing from the previous source whenever we want to observe a new one. In order do this, we would use switchMap. Under the hood, switchMap uses the MediatorLiveData that removes the initial source whenever the new source is added. In short, it does all the mechanism removing and adding a new Observer for us.
Now, if you want to go ahead and make your own custom data transformations, you should take a look at the MediatorLiveData class.
MediatorLiveData includes methods to add and remove source LiveData objects.You could then combine and propagate events from all these sources downstream.
Getting started with LiveData is simple, but there is a lot of potential for experimentation with this lifecycle aware observable. here is an example to refer — https://github.com/chethu/Android-Mediator-live-data-example
About
LiveData is part of the Lifecycle library which was designed to help you solve common Android Lifecycle challenges and to make your apps more maintainable and testable.
Источник
LiveData
public abstract class LiveData
extends Object
java.lang.Object | |
↳ | android.arch.lifecycle.LiveData |
MutableLiveData | LiveData which publicly exposes setValue(T) and postValue(T) method. |
MediatorLiveData | LiveData subclass which may observe other LiveData objects and react on OnChanged events from them. |
LiveData is a data holder class that can be observed within a given lifecycle. This means that an Observer can be added in a pair with a LifecycleOwner , and this observer will be notified about modifications of the wrapped data only if the paired LifecycleOwner is in active state. LifecycleOwner is considered as active, if its state is STARTED or RESUMED . An observer added via observeForever(Observer) is considered as always active and thus will be always notified about modifications. For those observers, you should manually call removeObserver(Observer) .
An observer added with a Lifecycle will be automatically removed if the corresponding Lifecycle moves to DESTROYED state. This is especially useful for activities and fragments where they can safely observe LiveData and not worry about leaks: they will be instantly unsubscribed when they are destroyed.
In addition, LiveData has onActive() and onInactive() methods to get notified when number of active Observer s change between 0 and 1. This allows LiveData to release any heavy resources when it does not have any Observers that are actively observing.
This class is designed to hold individual data fields of ViewModel , but can also be used for sharing data between different modules in your application in a decoupled fashion.
Summary
Public constructors
Public methods
Returns the current value.
Returns true if this LiveData has active observers.
Returns true if this LiveData has observers.
Adds the given observer to the observers list within the lifespan of the given owner.
Adds the given observer to the observers list.
Removes the given observer from the observers list.
Removes all observers that are tied to the given LifecycleOwner .
Protected methods
Called when the number of active observers change to 1 from 0.
Called when the number of active observers change from 1 to 0.
Posts a task to a main thread to set the given value.
Источник
Understanding LiveData in Android
Updating the UI of the application due to change in some data is one of the most used tasks in Android. For example, whenever you like some post on Instagram, then the like count will be increased and also the color of the like button will be changed to red from white. So, here we are changing the UI based on some data and there are many other examples of these kinds of UI change due to some change in data in Android.
So, these changes in the views of your app can be carried out with the help of ViewModel and to make the working of a ViewModel easy, Google introduced the concept of LiveData. LiveData is a part of Android Jetpack and in this blog, we are going to understand the concept of LiveData in Android.
What is LiveData?
Let’s first look at the definition mentioned in the official Android documentation:
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. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.
Let’s have a simpler definition now.
In simple words, LiveData is basically a data holder and it is used to observe the changes of a particular view and then update the corresponding change. It is lifecycle-aware i.e. whenever a data is updated or changed then the updates will be sent to only those app components which are in active state. If the app component is not active and in the future, if it becomes active, then the updated data will be sent to that app component. So, you need not worry about the lifecycle of the app component while updating data.
For example, if you are not using LiveData and you are updating some TextView with some value, then on rotation of the screen, you need to again set the new value in the TextView because the Activity will be recreated on screen rotation. But if you are using LiveData, all you need to do is just update the value and that’s it. No need to care about the lifecycle.
So, here are the things that will encourage you to use LiveData in your application:
- You can use LiveData with libraries like Room Persistent Library, Coroutines, etc.
- Once a data is modified/changed, the observers will be notified about the change
- But before notifying the observers, LiveData will check if the observer is live or not. If it is live, then the notification will be sent otherwise not. In this way, the crash due to stopped activities will be stopped.
- While using LiveData, you need not worry about unsubscribing any observers.
- If the inactive observer will be resumed in future, then the latest data will be sent to that observer.
- No need to worry about activity recreation due to screen rotation because only the updated data will be sent.
Four basic steps to work with LiveData
In order to use LiveData in your project, all you need to do is follow the below four steps:
- Firstly, for holding the data, you need to create a LiveData instance in your ViewModel.
- After creating the instance of LiveData, you need to set the data in the LiveData by using methods like setValue and postValue .
- After that, you need to return the LiveData so that it can be observed by some observer in the views like Activity or Fragments.
- And finally, you need to observe the data in your views with the help of observe method. In the observer, you need to define all the changes in the UI that you want to perform on data change.
After following the above four steps, whenever there is a change in the data stored in LiveData then all the observers associated with the LiveData will be notified if they are live otherwise they will be notified when they come into the resume state.
So, let’s see how we can code for the above four steps:
Step 1: Creating an instance of LiveData
Here, we are going to use MutableLiveData that will be used for updating the name .
Step 2: Set the data in LiveData
Here, we need to change/update the data in LiveData. The MutableLiveData publicly exposes two methods i.e. setValue and postValue to set the data in LiveData.
So, here are some of the points that you must think before using setValue and postValue :
- If you are working on the main thread, then both setValue and postValue will work in the same manner i.e. they will update the value and notify the observers.
- If working in some background thread, then you can’t use setValue . You have to use postValue here with some observer. But the interesting thing about postValue is that the value will be change immediately but the notification that is to be sent to observers will be scheduled to execute on the main thread via the event loop with the handler.
Here is the code for updating LiveData using setValue and postValue :
Step 3: Returning LiveData
After setting the data, you need to return the LiveData so that it can be observed in some view.
Step 4: Observe the data in some view
Finally, you need to observe the data in some view by using observers. One thing to be noted here is that only those observers will be notified that are active. When an observer comes from an inactive to an active state, then the updated data will be sent to it.
This is how you can use LiveData by just following the above four steps.
Conclusion
So, in this blog, we learned about LiveData and how to use it. We saw that if there is a change in data then that data will be reflected to all the observers associated with it but it only notifies the changes to the observers that are live or in the active state and not to that observer that are in the inactive state.
Hope you liked this blog. To learn more about some of the cool topics of Android, you can visit our blogging website. Also, you can learn how to use LiveData in Room persistent library from here.
Источник