【发布时间】:2019-11-22 00:27:47
【问题描述】:
我正在使用 Retrofit、LiveData、Room (Android AAC)。 NetworkBoundResource是googlesimple提供的网络源和房间结合的好帮手。
由于 Retrofit 2.6.0 引入了对挂起的内置支持,我尝试修改 NetworkBoundResource 以使用挂起功能代替 LiveDataCallAdapter,但遇到了很多麻烦。
这是我的修改:
abstract class NetworkBondResource<ResultType, RequestType>
@MainThread constructor() {
private val result = MediatorLiveData<Resource<ResultType>>()
private val supervisorJob = SupervisorJob()
init {
result.value = Resource.loading(null)
}
fun asLiveData() = result as LiveData<Resource<ResultType>>
suspend fun load() {
withContext(Dispatchers.Main) {
val dbSource = loadFromDb()
result.addSource(dbSource) { data ->
result.removeSource(dbSource)
if (shouldFetch(data)) {
// ! HERE--------------
GlobalScope.launch(Dispatchers.IO) {
fetchFromNetwork(dbSource)
}
} else {
result.addSource(dbSource) { newData ->
setValue(Resource.success(newData))
}
}
}
}
}
// others code...
}
问题是result.addSource(dbSource) 内的代码无法继承外部作用域。我必须使用GlobalScope 来启动一个新的协程,这将导致“协程泄漏”,因为它不受viewModel 范围的控制。
我还找到了another way。但是这个方案违背了single trusted source的原则,失去了NetworkBoundResource的核心作用。
任何想法都会受到赞赏。
【问题讨论】:
-
我也遇到了同样的情况,正在寻找解决方案,也许你可以试试看这个link
标签: android retrofit2 android-livedata kotlin-coroutines