使用
monarchy realm
数据库,dao
给出 liveData.
A repository
将 liveData
提供给 useCase
作为 flow
使用 .asFlow
上的 liveData.
useCase
需要在进行一些 flow
ViewModel
和其他验证后,将 filter,
返回到 map,
。 ViewModel
从 flow
收集 useCase
并将更新发布到本地 mutableLiveData.
A view
观察 liveData
的 mutableLiveData.
形式 View
接收更新!
//fragment.kt
fun initObserver() {
viewModel.itemsLiveData.observe(viewLifeCycleOwner) { list ->
onUpdateItems(list)
}
}
//viewModel.kt
private val _itemsLiveData = MutableLiveData<List<Items>>()
val itemsLiveData = _itemsLiveData
init {
getItems()
}
fun getItems() {
viewModelScope.launch(Dispatchers.IO) {
useCase.getItems().collectLatest { items ->
_itemsLiveData.postValue(items)
}
}
}
//usecase.kt (callbackFlow or suspendCancellableCoroutine?)
suspend fun getItems(): callbackFlow<List<Items>> {
repository.getItems().collectLatest { dbItems ->
val validList = dbItems.filter { it.isValid() }.map { it.toUiModel() }
if (validList.isNotEmpty()) {
trySendBlocking(validList)
} else {
trySendBlocking(defaultList)
}
}
//Cancel this coroutine scope and it's children.
awaitClose {
cancel()
}
//Close this channel. No more sending. Sending operation is closed.
channel.close()
}
suspend fun apiCall() {
val result = api.getItems()
if (result.isSuccessful) {
val items = result.body()?.items
if (items != null && items.isNotEmpty()) {
repository.saveItems(items)
}
}
}
//repository.kt
suspend fun getItems() = withContext(Dispatchers.Main) { dao.getItemsLiveData().asFlow() }
suspend fun saveItems(items: Items) = withContext(Dispatchers.Main) { dao.saveItems(items) }
//dao.kt
fun getItemsLiveData() = LiveData<Items>()
fun saveItems(items: Items)
但是,我有几个问题或疑问:
flow
?take(1)
中的first()
上使用repository.getItems()
还是useCase
?pull To Refresh,
操作时,我们将进行 API 调用并将数据保存到数据库中。我相信更新将按以下顺序进行:从数据库到repository,
到useCase,
到ViewModel,
到fragment.
但我怀疑useCase
,因为它取消了范围并关闭了通道。我怀疑它不会收到任何更新,直到我们再次调用 useCase.getItems
再次,开始从 repository.
收集流量,是吗?如果是,我们如何设置整个通信,以便每当数据库发生更改时fragment
始终收到更新,而无需在进行 API 调用后再次调用 useCase.getItems
函数?suspendCancellableCoroutine
而不是 callbackFlow
吗?