作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Retrofit、LiveData、Room (Android AAC)。 NetworkBoundResource
是googlesimple提供的网络资源和房间结合的好 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
控制范围。
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/
我是一名优秀的程序员,十分优秀!