【问题标题】:Can't execute Retrofit sync operation by Kotlin无法通过 Kotlin 执行 Retrofit 同步操作
【发布时间】:2020-03-05 23:08:41
【问题描述】:

在我的安卓应用中:

app/build.gradle

implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
implementation "com.squareup.retrofit2:converter-gson:2.6.0"
implementation "com.squareup.retrofit2:retrofit:2.6.0"

在我的界面中:

import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query


interface MyRestClient {

    @GET("/event")
    suspend fun getEvents(@Query("orgn") base: Int, @Query("event") quote: Int): Response<List<Event>>
}

我想同步调用这个方法。

所以我试试这个:

    import retrofit2.Call
    import retrofit2.Response

    class TransportService {
        companion object {
            private val myRestClient =
                RestClientFactory.createRestClient(MyRestClient ::class.java)

            suspend fun getEventSync(orgn: Int, event: Int): Response<*> {
                val call: Call<*> = myRestClient .getEvents(orgn, event)      
                   return call.execute()
                }

然后通过这个调用:

import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

 viewModelScope.launch(Dispatchers.Main) {
            val response = TransportService.getEvents(100, 200)

但我在这一行得到编译错误:

val call: Call<*> = myRestClient.getEvents(orgn, event)   

错误是:

Type mismatch: inferred type is Response<List<Event>> but Call<*> was expected

【问题讨论】:

    标签: android kotlin retrofit2.6


    【解决方案1】:

    这是我的解决方案:

     viewModelScope.launch(Dispatchers.Main) {
                Debug.d(TAG, "step_1")
                TransportService.getEvents(100, 200)
                Debug.d(TAG, "step_2")
                TransportService.getEvents(300, 400)
                Debug.d(TAG, "step_3")
                TransportService.getEvents(500, 600)
                Debug.d(TAG, "step_4")
            }
    

    在 TransportService.kt 中

    suspend fun getEvents(
                orgn: Int,
                event: Int
            ): Response<*> {
                return  waitressCallRestClient.getEvents(orgn, event)
            }
    

    在界面中:

    @GET("/event")
        suspend fun getEvents(@Query("orgn") base: Int, @Query("event") quote: Int): Response<List<Event>>
    

    因为我使用 retrofit 2.6suspend 函数作为结果 step_2 仅在完成 ​​TransportService.getEvents(100, 200) 后打印。 并且 step_2 仅在完成TransportService.getEvents(300, 400) 后打印,以此类推。

    所以这就是我需要的。我同步调用了getEvents()

    【讨论】:

      【解决方案2】:

      错误消息告诉您问题所在。

      val call: Call<*> = myRestClient.getEvents(orgn, event)   
      

      getEvents 返回Response&lt;List&lt;Event&gt;&gt;,但您正试图将其分配给Call&lt;*&gt;

      使用改造 2.6 和协程,您不再需要调用。

      getEventSync 函数不再有意义。您可以在调用点决定同步和异步。对于阻塞:

      val events: Reponse<List<Event>> = runBlocking {
              myRestClient.getEvents(orgn, event)
      }
      

      【讨论】:

      • 我添加了我的答案
      【解决方案3】:

      您在MyRestClient 接口中返回Response 类型,但在TransportService 中期望Call

      在您的TransportService 类中,将val call 的参数类型从Call&lt;*&gt; 更改为Response&lt;List&lt;Event&gt;&gt;

      另外,由于您希望同步执行此方法,您可能不需要在您的getEvents 方法上使用suspend 修饰符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-23
        • 2019-05-27
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 2019-02-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多