Android 开发进阶

Android lifecycle 的 Transformati

2020-11-17  本文已影响0人  JeffreyWorld

本文部分资料来源于, Android 开放官方文档:Transformations

Transformations 是用于 LiveData 类的转换。
您可以使用转换方法在观察者的整个生命周期中传递信息。 除非观察者观察返回的 LiveData 对象,否则不计算转换。由于转换是延迟计算的,因此与生命周期相关的行为将隐式传递,而无需其他显式调用或依赖项。

一、map

LiveData<Y> map (LiveData<X> source, 
                Function<X, Y> func)

将主线程上的给定函数应用于 LiveData 数据源发出的每个值,然后返回 LiveData,来发出结果值。给定的函数 func 将在主线程上执行。

假设你有一个名为 userLiveData 的 LiveData,其中包含用户数据,并且你需要显示通过连接用户的名字和姓氏创建的用户名。 你可以定义一个处理名称创建的函数,该函数将应用于 useLiveData 发出的每个值。

LiveData userLiveData = ...;
 LiveData userName = Transformations.map(userLiveData, user -> {
      return user.firstName + " " + user.lastName
 });

二、switchMap

LiveData<Y> switchMap (LiveData<X> trigger, 
                Function<X, LiveData<Y>> func)

创建一个 LiveData,将其命名为 swLiveData,它遵循以下流程:它对 trigger LiveData 的更改做出反应,将给定函数应用于 trigger LiveData 的新值,并将生成的 LiveData 设置为 swLiveData 的 “Backing” 的 LiveData。 “Backing” 的 LiveData 表示,它发出的所有事件都将由 swLiveData 重新传递。

如果给定的函数返回 null,则其他任何 LiveData 都不会 “backed” swLiveData。给定的函数 func 将在主线程上执行。
考虑具有包含用户 ID 的 LiveData 的情况。 每次发出新的用户 ID 时,你都想触发一个请求,从存储库中仍然返回的是 LiveData,去获得用户的对象与这个 ID 相对应。

userIdLiveData 是触发器,repository.getUserById 返回的 LiveData 是 “backing” LiveData。

在存储库包含 User(1,“ Jane”)和 User(2,“ John”)的情况下,当 userIdLiveData 值设置为“ 1”时,switchMap 将调用 getUser(1),这将返回一个 LiveData。 包含值 User(1,“ Jane”)。 因此,现在,userLiveData 将发出 User(1,“ Jane”)。 当存储库中的用户更新为 User(1,“ Sarah”)时,userLiveData 将自动得到通知,并发出 User(1,“ Sarah”)。

当使用 userId =“ 2” 调用 setUserId 方法时,userIdLiveData 的值将更改并自动触发从存储库获取 ID 为“ 2”的用户的请求。 因此,userLiveData 发出 User(2,“ John”)。 由repository.getUserById(1)返回的 LiveData 作为源数据被删除。

 MutableLiveData userIdLiveData = ...;
 LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
     repository.getUserById(id));

 void setUserId(String userId) {
      this.userIdLiveData.setValue(userId);
 }

另外个 demo :

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import com.worldtech.jetpack.logic.MainPageRepository
import com.worldtech.jetpack.logic.api.MainPageService
import com.worldtech.jetpack.logic.model.Discovery

class DiscoveryViewModel(repository: MainPageRepository) : ViewModel() {

    var dataList = ArrayList<Discovery.Item>()

    private var requestParamLiveData = MutableLiveData<String>()

    var nextPageUrl: String? = null

    val dataListLiveData = Transformations.switchMap(requestParamLiveData) { url ->
        liveData {
            val resutlt = try {
                val discovery = repository.refreshDiscovery(url)
                Result.success(discovery)
            } catch (e: Exception) {
                Result.failure<Discovery>(e)
            }
            emit(resutlt)
        }
    }


    fun onRefresh() {
        requestParamLiveData.value = MainPageService.DISCOVERY_URL
    }

    fun onLoadMore() {
        requestParamLiveData.value = nextPageUrl ?: ""
    }
}

lifecycle 架构其他一些常用的点介绍:

LiveData<T>:

内容为 T 类型数据的容器,可监听内容的变化且具有一定的实时性;
对外提供监听容器内容变化的接口 observe(LifecycleOwner, Observer);
会在适当的时期通知监听器;
适当的时期:激活状态( LifecycleRegistry 监听 fragment 生命周期);
外部需 MutableLiveData 才能改变容器内容;

MutableLiveData:

继承至 LiveData;
提供改变容器内容的接口 setValue/postValue;

MediatorLiveData:

继承至MutableLiveData;
可监听其他容器内容的变化,通过 addSource(source:LiveData, Observer);
addSource 还需在激活状态下才会有机会调用 addSource 中的 Observer (激活后,source 才会添加 Observer 作监听器)

推荐一个官方文档的链接:
Android 开放官方文档:将 Kotlin 协程与架构组件一起使用

推荐一个:
采用 Jetpack + 协程实现的 MVVM 架构,用 Kotlin 写的短视频 Android 客户端项目

上一篇下一篇

猜你喜欢

热点阅读