【问题标题】:How to use Kotlin Coroutine.LiveData + Retrofit for API call while showing a progress bar?如何在显示进度条的同时使用 Kotlin Coroutine.LiveData + Retrofit 进行 API 调用?
【发布时间】:2020-03-28 03:12:59
【问题描述】:

我正在尝试使用协程进行 API 调用并使用 MVVM 架构进行改造。我想在等待 API 响应就绪时显示进度条(超时 3 秒)。

View Model我使用的是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 所做的那样)?

【问题讨论】:

    标签: android kotlin retrofit android-livedata coroutine


    【解决方案1】:

    你可以这样做:

    val _progressBarVisibility = MutableLiveData<Int>() // Use this with postValue
    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)
    }
    

    之后在你的 Activity 中:

    viewModel.progressBarVisibility.observe(this, Observer{
      pbVisibilityView.visibity = it
    }
    

    如果您特别询问改造,这就是您可以做到的。

    在您的DataApi 界面中,您只需将方法标记为suspended:

    interface DataApi{
      @GET("endpointHere")
      suspend fun getData() : Result<Data>
    }
    

    其余的就像我上面描述的那样。只需将getConfigurations(4) 替换为getData()

    【讨论】:

      猜你喜欢
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多