Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

338
Vistas
Kotlin - OkHttp - Return from onResponse

I'm new in Android Development and I'm trying to fetch json data from DarkSky API, using OkHttp and GSon. Problem is that I need to somehow return response from onResponse method but it's always null.

Here is my code:

class DarkSky : Callback {

    private var url: String? = null
    private var forecast: Forecast? = null

    fun fetchJson(lat: Double, long: Double): Forecast? {
        this.url = "${Constants.DARK_SKY_BASE_URL}/${Constants.DARK_SKY_KEY}/$lat,$long?exclude=hourly,flags,offset"

        val request = Request.Builder().url(url!!).build()

        val client = OkHttpClient()
        client.newCall(request).enqueue(this)


        return this.forecast // when I debug this its NULL

    }


    override fun onFailure(call: Call, e: IOException) {
        println("error")
    }

    override fun onResponse(call: Call, response: Response) {

        if (response.isSuccessful) {
            val body = response.body()?.string()

            val gson = GsonBuilder().create()
            val forecast = gson.fromJson(body, Forecast::class.java)

            parse(forecast)
        }
    }

    private fun parse(response: Forecast) {
        this.forecast = response  //when I debug this, it contains data I need.
    }

}

EDIT:

Made it work with BlockingQueue. But don't know. Is it a good idea?

class DarkSky {

    private var url: String? = null
    private var forecast: Forecast? = null

    fun fetchJson(lat: Double, long: Double): ArrayBlockingQueue<Forecast>? {
        this.url = "${Constants.DARK_SKY_BASE_URL}/${Constants.DARK_SKY_KEY}/$lat,$long?exclude=hourly,flags,offset"

        val request = Request.Builder().url(url!!).build()

        val blockingQueue: ArrayBlockingQueue<Forecast> = ArrayBlockingQueue(1) // <<<

        val client = OkHttpClient()
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                println("error")
            }

            override fun onResponse(call: Call, response: Response) {

                if (response.isSuccessful) {
                    val body = response.body()?.string()

                    val gson = GsonBuilder().create()
                    val forecast = gson.fromJson(body, Forecast::class.java)

                    blockingQueue.add(forecast) // <<<
                }
            }
        })

        return blockingQueue
    }

}

Don't want to learn bad practices.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

That is because

client.newCall(request).enqueue(this)

will execute asynchronously in the background thread. So, by the time you are returning, it doesn't actually have a value assigned.

Solution:

You probably need to pass an object of a class which conforms certain interface and invokes a method of that interface.

Here are changes you need to do

class DarkSky : CallBack {

    private var url: String? = null
    private var forecast: Forecast? = null
    private var onRequestCompleteListener : OnRequestCompleteListener? =null

    fun fetchJson(lat: Double, long: Double,callback : OnRequestCompleteListener) {
        this.onRequestCompleteListener = callback
        this.url = "${Constants.DARK_SKY_BASE_URL}/${Constants.DARK_SKY_KEY}/$lat,$long?exclude=hourly,flags,offset"

        val request = Request.Builder().url(url!!).build()

        val client = OkHttpClient()
        client.newCall(request).enqueue(this)

    }


    override fun onFailure(call: Call, e: IOException) {
        onRequestCompleteListener?.onError()
        println("error")
    }

    override fun onResponse(call: Call, response: Response) {

        if (response.isSuccessful) {
            val body = response.body()?.string()

            val gson = GsonBuilder().create()
            val forecast = gson.fromJson(body, Forecast::class.java)

            parse(forecast)
        }
        onRequestCompleteListener?.onSuccess(forecast)
    }

    private fun parse(response: Forecast) {
        this.forecast = response  //when I debug this, it contains data I need.
    }

}


interface OnRequestCompleteListener{
    fun onSuccess(forcast :Forecast)
    fun onError()
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda