【发布时间】:2020-11-20 20:49:31
【问题描述】:
我刚开始工作的公司使用所谓的 Navigator,我现在将其解释为无状态 ViewModel。我的 Navigator 收到一些用例,每个用例都包含 1 个挂起函数。任何这些用例的结果都可能最终出现在一个 LiveData 中。 Navigator 没有协程作用域,因此我将使用fetchValue() 将作用域挂起的职责传递给Fragment。
项目中的大多数当前代码在数据层中都有 LiveData,我尽量不这样做。因此,他们的实时数据从视图链接到 dao。
我的简化课程:
class MyFeatureNavigator(
getUrl1: getUrl1UseCase,
getUrl1: getUrl1UseCase
) {
val url = MediatorLiveData<String>()
fun goToUrl1() {
url.fetchValue { getUrl1() }
}
fun goToUrl2() {
url.fetchValue { getUrl2() }
}
fun <T> MediatorLiveData<T>.fetchValue(provideValue: suspend () -> T) {
val liveData = liveData { emit(provideValue()) }
addSource(liveData) {
removeSource(liveData)
value = it
}
}
}
class MyFeatureFragment : Fragment {
val viewModel: MyFeatureViewModel by viewModel()
val navigator: MyFeatureNavigator by inject()
fun onViewCreated() {
button.setOnClickListener { navigator.goToUrl1() }
navigator.url.observe(viewLifecycleOwner, Observer { url ->
openUrl(url)
})
}
}
我的两个问题:
-
fetchValue()是将挂起函数链接到 LiveData 的好方法吗?会不会漏?还有其他问题吗? - 我只在数据层使用协程(和流)的主要原因是“因为 Google 这么说”。这有什么更好的理由?并且:在与项目和当前良好的编码实践保持一致方面,最佳权衡是什么?
【问题讨论】:
标签: android kotlin android-livedata kotlin-coroutines