我在想,有没有任何方法可以构建您的代码,这样您就可以像这样进行改装调用:
例如在主活动中:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val data = userRepository.getUsers().await()
}
onCreate()
函数的内容在主线程上调用。您不能等待长时间运行的操作,如主线程上的IO或Reform调用。
你可以把它推到这样的协同游戏中。在请求数据后必须按顺序调用的所有代码都必须进入协程。
当使用wait或suspend函数在Reform中检索某些内容时,您必须将调用包装在try/catch中,这样您就可以处理由于检索无法完成而发生的任何IO错误。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
val data = try {
userRepository.getUsers().await()
} catch (e: HttpException) {
// Do something with HTTP failures here.
return@launch
} catch (e: Exception) {
// Do something when connection can't be made here.
return@launch
}
// Do something with data inside the coroutine here.
}
}
请注意,如果您使用协程,您还可以在API中将您的函数定义为suspend函数,而不是返回Call的函数,因此请更改之类的内容
@GET("users")
fun getUsers(@Path("users") users: String): Call<List<User>>
进入
@GET("users")
suspend fun getUsers(@Path("users") users: String): List<User>
并且您将不需要await()
呼叫。
或者,您可以使用回调,而不是协同程序,但它看起来更混乱:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
userRepository.getUsers().enqueue(object: Callback<List<User>> {
override fun onResponse(call: Call<List<User>>, response: Response<List<User>>) {
if (response.isSuccessful) {
val data = body!!
// Do something with response data here.
} else {
// Do something with HTTP failures here.
}
}
override fun onFailure(call: Call<List<User>>, t: Throwable) {
// Do something when connection can't be made here.
}
})
}
无论您是否使用协同程序,您都可能应该在ViewModel中而不是直接在"活动"中执行此请求。这样,就不必每次用户旋转屏幕时都重新生成请求。