Che*_*nhe 8 android retrofit2 android-livedata kotlin-coroutines
我正在使用 Retrofit、LiveData、Room(Android AAC)。NetworkBoundResource是googlesimple提供的网络源码和房间结合的好帮手。
由于Retrofit 2.6.0引入了对暂停的内置支持,我尝试修改NetworkBoundResource使用暂停功能instaed,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...
}
Run Code Online (Sandbox Code Playgroud)
问题是result.addSource(dbSource)无法继承外部范围内的代码。我必须用来GlobalScope启动一个新的协程,这将导致“协程泄漏”,因为它不受viewModel范围控制。
我也找到了另一种方法。但这种方案违反了单一可信来源的原则,失去了核心作用NetworkBoundResource。
任何想法将不胜感激。
小智 1
我也遇到了同样的问题,我的解决方案是这样的。由于这些原因,我建议您不要使用 GlobalScope 。明确 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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1290 次 |
| 最近记录: |