gpt4 book ai didi

android - 如何在 Retrofit 中使用具有暂停乐趣的 NetworkBoundResource

转载 作者:行者123 更新时间:2023-12-03 09:39:45 24 4
gpt4 key购买 nike

我正在使用 Retrofit、LiveData、Room (Android AAC)。 NetworkBoundResourcegooglesimple提供的网络资源和房间结合的好 helper .

由于 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的核心作用.

任何想法将不胜感激。

最佳答案

我也遇到了同样的问题,我的解决方法是这样的。我建议您不要使用 GlobalScope for these reasons .明确 result.addSoruce 只能在主线程中声明。希望对您有所帮助,如果有更好的解决方案请告诉我。

 private val result = MediatorLiveData<Resource<ResultType>>()
private val supervisorJob = SupervisorJob()

suspend fun load(): NetworkBoundResource<ResultType, RequestType> {

val context = Dispatchers.IO
context + supervisorJob


withContext(Dispatchers.Main) {
result.value = Resource.loading(null)
val dbResult = loadFromDb()
result.addSource(dbResult){data->
result.removeSource(dbResult)
if (shouldFetch(data)){
try {
CoroutineScope(context).launch {
fetchFromNetwork(dbResult)
}
}catch (e:Exception){
Timber.i("NetworkBoundResource: An error happened: $e")
result.addSource(dbResult){newData->
setValue(Resource.error(e.message!!, newData))
}
}
}else{
Timber.i("NetworkBoundResource: Return data from local database")
result.addSource(dbResult){newData->
setValue(Resource.success(newData))
}

}
}

}

return this

}

关于android - 如何在 Retrofit 中使用具有暂停乐趣的 NetworkBoundResource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57003541/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com