繁体   English   中英

如何用 Flow 替换 LiveData

[英]How to replace LiveData with Flow

我有一个名为sortOrderLiveData ,然后我有另一个名为myData的变量,它观察对sortOrder的任何更改并相应地填充数据。

class TestViewModel @ViewModelInject constructor() : ViewModel() {

    private val sortOrder = MutableLiveData<String>()

    val myData = sortOrder.map {
        Timber.d("Sort order changed to $it")
        "Sort order is $it"
    }

    init {
        sortOrder.value = "year"
    }

}

在活动中观察

class TestActivity : AppCompatActivity() {

    private val viewModel: TestViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
        
        // Observing data
        viewModel.myData.observe(this) {
            Timber.d("Data is : $it")
        }
    }
}

  • 如何在 output 中没有任何变化的情况下用Flow/StateFlow API 替换上述场景?

如果您无法将映射的冷流转换为热流,它会在您每次收集它时重新启动流(就像重新创建 Activity 时一样)。 这就是冷流的工作原理。

我有一种感觉,他们会充实 StateFlow/SharedFlow 的转换函数,因为将它们转换为冷流并不得不将它们转回热流感觉非常尴尬。

如果您不想手动 map 明确第一个元素,则公共 Flow 必须是 SharedFlow,因为stateIn function 要求您直接提供初始 state。

    private val sortOrder = MutableStateFlow("year")

    val myData = sortOrder.map {
        Timber.d("Sort order changed to $it")
        "Sort order is $it"
    }.shareIn(viewModelScope, SharingStarted.Eagerly, 1)

或者您可以创建一个单独的 function,它在map中调用,也在stateIn function 调用中调用。

    private val sortOrder = MutableSharedFlow<String>()
    
    private fun convertSortOrder(order: String): String {
        Log.d("ViewModel", "Sort order changed to $order")
        return "Sort order is $order"
    }

    val myData = sortOrder.map {
        convertSortOrder(it)
    }.stateIn(viewModelScope, SharingStarted.Eagerly, convertSortOrder("year"))

我有一个名为sortOrderLiveData ,然后我有另一个名为myData的变量,它观察对sortOrder的任何更改并相应地填充数据。

class TestViewModel @ViewModelInject constructor() : ViewModel() {

    private val sortOrder = MutableLiveData<String>()

    val myData = sortOrder.map {
        Timber.d("Sort order changed to $it")
        "Sort order is $it"
    }

    init {
        sortOrder.value = "year"
    }

}

在活动中观察

class TestActivity : AppCompatActivity() {

    private val viewModel: TestViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
        
        // Observing data
        viewModel.myData.observe(this) {
            Timber.d("Data is : $it")
        }
    }
}

问题

  • 如何在不更改 output 的情况下用Flow/StateFlow API 替换上述场景?

从片段/活动的角度来看,您必须创建一个作业来收集onStart()中的流并在onStop()中取消它。 使用lifecycleScope.launchWhenStarted将使流即使在后台也保持活动状态

使用绑定库轻松迁移到Flow 我有偏见,不过。

请参阅有关它的媒体文章

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM