Как сделать синхронный звонок в сопрограмме - PullRequest
1 голос
/ 28 октября 2019

Я хочу сделать мой сетевой запрос синхронным, потому что ввод второго запроса происходит с выхода первого запроса.

override fun onCreate(savedInstanceState: Bundle?) {

retrofit1 =Retrofit.Builder()
        .baseUrl("https://jsonplaceholder.typicode.com/").addConverterFactory(GsonConverterFactory.create()).build()

retrofit2 =Retrofit.Builder()
        .baseUrl("https://samples.openweathermap.org/").addConverterFactory(GsonConverterFactory.create()).build()

button.setOnClickListener { view ->
CoroutineScope(IO).launch {
fakeApiRequest()
}}

В моем fakeApiRequest () я делаю два сетевых запроса.

private suspend fun fakeApiRequest() {
val result1 :Geo?= getResult1FromApi()
val result2: Long? = getResult2FromApi(result1)}

Поскольку это асинхронный вызов, я получаю исключение нулевого указателя в моем методе getResult2FromApi (result1), поскольку переданный аргумент равен нулю.

Чтобы устранить эту проблему, мне пришлосьдобавьте задержку (1500) при первом вызове.

private suspend fun getResult1FromApi(): Geo? {
val service:CallService = retrofit1!!.create(CallService::class.java)
val call = service.getUsers()
call.enqueue(object : Callback<List<User>> {
override fun onResponse(call: Call<List<User>>, response: Response<List<User>>) {
g = users.get(0).address.geo
}
override fun onFailure(call: Call<List<User>>, t: Throwable) {

}
})
delay(1500)
return g
}

-----------------------------------------------------------

private suspend fun getResult2FromApi(result1: Geo?): Long? {
val service2:CallService = retrofit2!!.create(CallService::class.java)
val call2 = service2.getWeather(result1?.lat!!, result1.lng,"b6907d289e10d714a6e88b30761fae22")
call2.enqueue(object : Callback<WeatherData> {
override fun onResponse(call: Call<WeatherData>, response: Response<WeatherData>) {

}
override fun onFailure(call: Call<WeatherData>, t: Throwable) {
}
})
return dt
}

В любом случае я могу сделать это синхронно, чтобы мне не приходилось пропускать время задержки.

1 Ответ

2 голосов
/ 29 октября 2019

Вы не правильно реализовали функцию приостановки. Вы должны использовать suspendCoroutine:

suspend fun getResult1FromApi(): Geo? = suspendCoroutine { continuation ->
    val service = retrofit1!!.create(CallService::class.java)
    service.getUsers().enqueue(object : Callback<List<User>> {
        override fun onResponse(call: Call<List<User>>, response: Response<List<User>>) {
            continuation.resume(response.result.getOrNull(0)?.address?.geo)
        }
        override fun onFailure(call: Call<List<User>>, t: Throwable) {
            continuation.resumeWithException(t)
        }
    })
}

Теперь ваша функция синхронна и возвращает объект Geo.

...