我正在尝试使用协程进行API调用,并对MVVM体系结构进行改进。我想在等待API响应准备就绪(超时3秒)的同时显示进度栏。
在视图模型中,我正在使用Coroutine.LiveData
class BootstrapViewModel: ViewModel() {
private val repository : ConfigRepository =
ConfigRepository()
val configurations = liveData(Dispatchers.IO) {
val retrievedConfigs = repository.getConfigurations(4)
emit(retrievedConfigs)
}
}
到目前为止,我在活动中仅是模拟API调用以更新进度条:
launch {
// simulate API call
val configFetch = async(Dispatchers.IO) {
while (progressState.value != 100) {
progressState.postValue(progressState.value?.plus(1))
delay(50)
}
}
// suspend until fetch is finished or return null in 3 sec
val result = withTimeoutOrNull(3000) { configFetch.await() }
if (result != null) {
// todo: process config... next steps
} else {
// cancel configFetch
configFetch.cancel()
// show error
}
}
我还可以如下观察实时数据并正常工作:
bootstrapViewModel.configurations.observe(this, Observer {
//response is ready
})
一切正常分离。但是,当我尝试在协程范围内使用livedata时,情况会变得混乱。无论如何, await()是否有协程实时数据(就像我对 configFetch 所做的那样)?
答案 0 :(得分:0)
您可以这样做:
val _progressBarVisibility = MutableLiveData<Int>()
val progressBarVisibility: LiveData<Int> = _progressBarVisibility
val configurations = liveData(Dispatchers.IO) {
progressBarVisibility.postValue(View.VISIBLE)
// you can just stimulate API call with a delay() method
delay(3000) //3 seconds
val retrievedConfigs = repository.getConfigurations(4)
progressBarVisibility.postValue(View.GONE)
emit(retrievedConfigs)
}
之后在“活动”中:
viewModel.progressBarVisibility.observe(this, Observer{
pbVisibilityView.visibity = it
}
如果您特别要求翻新,这就是您的方法。
在您的DataApi
界面中,您只需将方法标记为suspend
ed:
interface DataApi{
@GET("endpointHere")
suspend fun getData() : Result<Data>
}
其余的就像我上面描述的那样。只需将getConfigurations(4)
替换为getData()