【发布时间】:2020-02-22 16:20:52
【问题描述】:
我正在尝试将 Android MVVM 模式与存储库类一起使用,并将 Retrofit 用于网络调用。我有一个常见的问题,就是无法让协程等待网络响应返回。
这个方法在我的ViewModel类中:
private fun loadConfigModel() {
val model = runBlocking {
withContext(Dispatchers.IO) {
configModelRepository.getConfigFile()
}
}
configModel.value = model
}
在ConfigModelRepository,我有这个:
suspend fun getConfigFile(): ConfigModel {
val configString = prefs.getString(
ConfigViewModel.CONFIG_SHARED_PREF_KEY, "") ?: ""
return if (configString.isEmpty() || isCacheExpired()) {
runBlocking { fetchConfig() }
} else {
postFromLocalCache(configString)
}
}
private suspend fun fetchConfig(): ConfigModel {
return suspendCoroutine { cont ->
dataService
.config() // <-- LAST LINE CALLED
.enqueue(object : Callback<ConfigModel> {
override fun onResponse(call: Call<ConfigModel>, response: Response<ConfigModel>) {
if (response.isSuccessful) {
response.body()?.let {
saveConfigResponseInSharedPreferences(it)
cont.resume(it)
}
} else {
cont.resume(ConfigModel(listOf(), listOf()))
}
}
override fun onFailure(call: Call<ConfigModel>, t: Throwable) {
Timber.e(t, "config fetch failed")
cont.resume(ConfigModel(listOf(), listOf()))
}
})
}
}
我的代码运行到dataService.config()。它永远不会进入onResponse 或onFailure。网络调用正确地进行并返回(我可以使用 Charles 看到这一点),但协程似乎没有在监听回调。
所以,我的问题是通常的问题。如何让协程阻塞,以便它们等待来自Retrofit 的回调?谢谢。
【问题讨论】:
-
你可以用
suspend标记你的Retrofit API调用并让它返回ConfigModel,而不是使用旧的回调机制和suspendCoroutine。
标签: android kotlin retrofit2 kotlin-coroutines