livedata
map和switchmap的区别
Map() is conceptually identical to the use in RXJava, basically you are changing a parameter of LiveData in another one
SwitchMap() instead you are going to substitute the LiveData itself with another one! Typical case is when you retrieve some data from a Repository for instance and to “eliminate” the previous LiveData (to garbage collect, to make it more efficient the memory usually) you pass a new LiveData that execute the same action( getting a query for instance)
译文:相反,您将用另一个替换 LiveData 本身! 典型的情况是,例如,当您从存储库中检索一些数据并“消除”以前的 LiveData(垃圾收集,通常使内存更有效)时,您传递一个执行相同操作的新 LiveData(获取查询 实例)
TRANSFORMATIONS:
Transformation basically applies a function to the values stored in the LiveData object and propagates the result to the downstream. There are currently two types of Transformations we have.
- [**Transformations.map**](https://developer.android.com/reference/android/arch/lifecycle/Transformations#map(android.arch.lifecycle.LiveData, android.arch.core.util.Function)): The map lets you apply a function to the output of LiveData and then propagates the result to the downstream.
- [**Transformations.switchMap**:](https://developer.android.com/reference/android/arch/lifecycle/Transformations.html#switchMap(android.arch.lifecycle.LiveData, android.arch.core.util.Function>)) The swicthMap function transformation is a lot like a map but for mapping function that emits LiveData instead of values. Again switchMap functions propagate LiveData to downstream instead of single value.
EXAMPLE OF TRANSFORMATIONS.MAP:
Let’s take a scenario where we need to show Snackbar whenever a new user added to the database. The Snackbar shows data of a custom String with username added in it.
You see a demo right, let’s create our ViewModel class to hold the LiveData of User.
TRANSFORMATIONVIEWMODEL CLASS:
1 | |
There are two things noticeable here.
- First, we are not exposing our user LiveData to publically. We have given a public function to just add the User object. By doing this we’re keeping our Immutability principle.
- Second, for adding the map Transformations we need to provide source LiveData and function from which you need to return your custom value. You see in our case we’re returning a custom String with username add in it.
So, we create our ViewModel and LiveData with map Transformations, let’s see how we gonna use this ViewModel inside our Activity.
MAINACTIVITY:
1 | |
The Activity is very basic, in here we’re only observing our LiveData instance. Whenever the user object added to LiveData it automatically calls the onChanged method with the custom String.
EXAMPLE OF TRANSFORMATIONS.SWITCHMAP:
Let’s take another scenario where I need to search user by username and show the result inside the RecyclerView.
You see the demo right let’s create our ViewModel class to search users with the name.
1 | |
You see in our ViewModel class we’re getting the data from our UserRepo class. So, whenever something is searched, we’ll get users with the name, then the repository creates a new instance of LiveData and returned the list of users. And finally based on the result we display the data.
To clarify the things between [*map*](https://developer.android.com/reference/android/arch/lifecycle/Transformations#map(android.arch.lifecycle.LiveData, android.arch.core.util.Function)) and [switchMap](https://developer.android.com/reference/android/arch/lifecycle/Transformations.html#switchMap(android.arch.lifecycle.LiveData, android.arch.core.util.Function>)), I use [map](https://developer.android.com/reference/android/arch/lifecycle/Transformations#map(android.arch.lifecycle.LiveData, android.arch.core.util.Function)) method so that, we could see what happened if we use [map](https://developer.android.com/reference/android/arch/lifecycle/Transformations#map(android.arch.lifecycle.LiveData, android.arch.core.util.Function)) method instead of [*swicthMap*](https://developer.android.com/reference/android/arch/lifecycle/Transformations.html#switchMap(android.arch.lifecycle.LiveData, android.arch.core.util.Function>)) when we need to return LiveData.
PROBLEM:
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. Now, how do we solve this problem…?
译文:
假设我们正在寻找用户名 Alice。 存储库正在创建该 User LiveData 类的新实例,之后,我们显示用户。 一段时间后,我们需要查找用户名 Bob,存储库会创建一个 LiveData 的新实例,并且我们的 UI 订阅 LiveData。 所以此时,我们的 UI 订阅了两个 LiveData 实例,因为我们从未删除前一个。 因此,这意味着每当我们的存储库更改用户的数据时,它都会发送两次订阅。 现在,我们如何解决这个问题……?
SOLUTION:
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 to this, we would use [switchMap](https://developer.android.com/reference/android/arch/lifecycle/Transformations.html#switchMap(android.arch.lifecycle.LiveData, android.arch.core.util.Function>)). Under the hood, [switchMap](https://developer.android.com/reference/android/arch/lifecycle/Transformations.html#switchMap(android.arch.lifecycle.LiveData, android.arch.core.util.Function>)) 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.
译文:
我们真正需要的是一种机制,当我们想观察一个新的来源时,它可以让我们停止从以前的来源观察。 为此,我们将使用 switchMap。 在底层,switchMap 使用 MediatorLiveData,只要添加了新源,它就会删除初始源。 简而言之,它为我们完成了删除和添加新观察者的所有机制。
Now our ViewModel class will look like this.
1 | |
All the code remain the same instead of the*[ switchMap](https://developer.android.com/reference/android/arch/lifecycle/Transformations.html#switchMap(android.arch.lifecycle.LiveData, android.arch.core.util.Function>))* method. Now here we only need our Activity class to observe this LiveData. The following shows the MainActivity class.
1 | |
The Activity is very basic. After setting the RecyclerView properties, whenever the user clicks the button we’re calling our ViewModel class function to search the users with a username. And in the last, we simply observing the LiveData coming from our ViewModel class.
Alright, guys, I’m going to end this blog here. You can also download the complete source code of the above example.
If you’ve any queries regarding this post on Transformations or any problem with LiveData please do comment below.
Thank you for being here and keep reading…
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

