简体   繁体   English

Android Kotlin Retrofit,在suspend外等待响应

[英]Android Kotlin Retrofit, wait for response outside suspend

I've got into a situation where I need to call an endpoint, and wait for the response before continuing the flow我遇到了需要调用端点并在继续流程之前等待响应的情况

Sadly, I can't make the function 'suspend', since it will require a heavy refactor and I prefer to 'hack' it this once可悲的是,我不能让 function “暂停”,因为它需要大量的重构,我更愿意“破解”一次

I've tried waiting for event signal, waiting for a value, using RunBlocking with 'await()', non worked, and await never fires back (response is received when using.enqueue())我试过等待事件信号,等待一个值,使用带有'await()'的RunBlocking,没有工作,并且等待永远不会回火(使用.enqueue()时收到响应)

All I need is this to work, i don't mind the UI to freeze, the user to wait, or the code to be ugly.我只需要这个工作,我不介意 UI 冻结、用户等待或代码丑陋。 There is a 2 second timeout and its a sacrifice i'm willing to take有 2 秒的超时,这是我愿意做出的牺牲

I'm not an android (or ios) developer, so i'll be glad to get any tips我不是 android(或 ios)开发人员,所以我很高兴得到任何提示

Attaching my code:附上我的代码:

API Interface API接口

import com.google.gson.annotations.SerializedName
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

interface ITaxForAddressApi {
    @POST("/myapi")
    fun getTaxForAddress(@Body body: TaxForAddressBodyRequest): Call<TaxRateEntity>
}

data class TaxForAddressBodyRequest(
    @SerializedName("address") val address: TaxForAddressBodyAddress
)

data class TaxForAddressBodyAddress(
    @SerializedName("streetAddress") val streetAddress: String,
    @SerializedName("city") val city: String,
    @SerializedName("state") val state: String,
    @SerializedName("zip") val zip: String,
    @SerializedName("country") val country: String
)

data class TaxRateEntity(@SerializedName("tax") val taxRate: Double)

Calling code:调用代码:

val addressBody = 
    TaxForAddressBodyAddress(
        shippingAddress.street,
        shippingAddress.city,
        shippingAddress.state,
        shippingAddress.zipCode,
        shippingAddress.country
        )
val taxRequest = TaxForAddressBodyRequest(addressBody)


val taxApiRequest = taxForAddressApi.getTaxForAddress(taxRequest)
taxApiRequest.enqueue(SafeCallback(object : CallbackResponseListener<TaxRateEntity> {
            override fun onSuccess(response: TaxRateEntity) {
                'Do Something here'
            }

            override fun onFailure(t: Throwable) {
                'Alert'
            }
        }))
}

Attempt with runBlocking (with try-catch of course):尝试使用 runBlocking(当然使用 try-catch):

runBlocking {
    val tax = taxForAddressApi.getTaxForAddress(taxRequest).await()
}

Retrofit's Call has an execute() method that you can invoke if you're fine with blocking the calling thread and you need to get the response synchronously. Retrofit 的Call有一个execute()方法,如果您可以阻止调用线程并且需要同步获取响应,则可以调用该方法。 Keep in mind that you might need to disable StrictMode which would throw a NetworkOnMainThreadException by default.请记住,您可能需要禁用StrictMode ,这会在默认情况下引发NetworkOnMainThreadException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM