【发布时间】:2022-08-21 15:01:06
【问题描述】:
我是 Android/Kotlin 的新手,我正在制作一个应用程序,它使用 Room 缓存从网络加载不同的数据,并决定使用“网络绑定资源”算法(简称 NBR),可以简化为:
inline fun <ResultType, RequestType> networkBoundResource(
crossinline query: () -> Flow<ResultType>,
crossinline fetch: suspend () -> RequestType,
crossinline saveFetchResult: suspend (RequestType) -> Unit,
crossinline shouldFetch: (ResultType) -> Boolean = { true }
) = flow {
val data = query().first()
val flow = if (shouldFetch(data)) {
emit(Resource.Loading(data))
try {
saveFetchResult(fetch())
query().map { Resource.Success(it) }
} catch (throwable: Throwable) {
query().map { Resource.Error(throwable, it) }
}
} else {
query().map { Resource.Success(it) }
}
emitAll(flow)
}
这是来自 Coding in Flow 的确切示例,非常类似于 Google 的 Github 浏览器实现与 LiveData 以及我见过的更多示例。 Resource 类是一个简单的状态+数据持有者,如下所示:
sealed class Resource<out R> {
class Success<out T>(val data: T) : Resource<T>()
class Error<out T>(val exception: Throwable, val data: T? = null) : Resource<T>()
class Loading<out T>(val data: T? = null) : Resource<T>()
}
但是在我的存储库类中实现这个之后,我发现了一些我无法在任何地方找到解决方案的问题:
-
如何强制刷新数据?我创建了一个单独的函数,它重用
fetch和saveFetchResult实现将数据从网络放入数据库,但我需要从 NBR 流收集器和挂起刷新函数刷新 UI 加载指示器,因为 NBR 永远不会为我重新发出加载状态。它有效,但感觉很糟糕。 -
在 NBR 中出错时,它会发出将任何 DB 更新值转换为
Resource.Error的流,即使是在成功刷新后出现的值,这会导致在 UI 中重复相同的错误消息,即使刷新时一切都很好。 -
当这个 NBR 被多个用例重用时,如何防止被多次提取?我是否需要整个功能的互斥锁?
标签: android kotlin kotlin-flow