在Android网络请求中使用Call〈>和暂停功能的困惑与改进

brvekthn  于 2023-03-16  发布在  Android
关注(0)|答案(2)|浏览(120)

在搜索错误的答案后,我的函数 fun getRestaurants():Call 不能挂起,我发现at this question你不能把挂起的函数和Call〈〉返回结合起来,我的问题解决了,但是我仍然不完全明白什么时候使用Call〈〉,什么时候挂起函数,至少在我向API发出@GET和@POST请求的这个上下文中,因为我知道有数据的输入和输出,因此最好使用挂起的函数,但在这种情况下调用的目的是什么。

interface RestaurantsApiService {
@GET("restaurants?populate=*")
fun getRestaurants(): Call<Restaurants>
}

interface RestaurantsApiService {
@GET("restaurants?populate=*")
suspend fun getRestaurants(): Restaurants
}

目前,在我的应用程序中,我正在使用Call,因为我正在学习的书中使用了Call,尽管它后来将Call更改为一个挂起的函数,但它并没有真正解释为什么这样做或这样做的好处是什么。
我知道并理解为什么要使用协程以及如何处理协程,当我在另一个函数/瓦尔等中调用 getRestaurants() 时,我可以做到这一点,但我的怀疑恰恰在于 getRestaurants()

aiazj4mn

aiazj4mn1#

Call是在你根本不使用协程的时候使用的。大多数情况下,它会用在纯Java项目中。如果你使用协程,使用它没有意义,除非你在一个遗留项目中工作,那里有一些模块还没有使用协程。然后你可以使用Call,在一个协程中,你会在它上面调用await(),以一种挂起的、同步的方式获得结果。

vbopmzt1

vbopmzt12#

你甚至可以把Callcoroutines一起使用。使用getRestaurants().execute()。这是一个阻塞调用。所以,你可以在一个协程作用域内使用它。

fun callInsideCoroutine() = CoroutineScope(Dispatchers.IO).launch {
    val result = restaurantsApiService.getRestaurants().execute()
}

由于不能直接将整个callInsideCoroutine()方法放入try...catch块中,因此使用以下扩展方法来处理异常:

fun <T> Call<T>.execute(onError: ((e: Exception) -> Unit)? = null): Response<T>? {
    return try {
        execute()
    } catch (e: Exception) {
        onError?.invoke(e)
        null
    }
}

相关问题