[英]How to await Retrofit call, with Kotlin?
我在想,有什么方法可以構建你的代碼,所以你可以像這樣進行 Retrofit 調用:
例如在 MainActivity 中:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val data = userRepository.getUsers().await()
}
onCreate()
function 的內容在主線程上調用。 您不能等待主線程上的 IO 或 Retrofit 調用等長時間運行的操作。
您可以將其推送到這樣的協程中。 請求數據后必須按順序調用的所有代碼必須在協程內部為 go。
當使用 await 或暫停 function 以檢索 Retrofit 中的內容時,您必須將調用包裝在 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.
}
}
Note that if you're using coroutines, you might as well define your function in your API as a suspend function instead of a function that returns a Call, so change something like
@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 中而不是直接在 Activity 中執行此請求。 這樣,每次用戶旋轉屏幕時都不必重新發出請求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.