Как передать объект из функции в созданный метод в android - PullRequest
0 голосов
/ 16 февраля 2020

Привет У меня есть следующий код:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button_search.setOnClickListener {
            val search = editText_user_search.text.toString()
            fetchJson(search)
            val intent = Intent(this, WeatherForecast::class.java)
        }

    }
}

private fun fetchJson(userSearch: String){
    println("Attempting to fetch JSON")

    val url = "https://api.openweathermap.org/data/2.5/weather?q=$userSearch&appid=MY_API_KEY"

    //val url = "https://api.letsbuildthatapp.com/youtube/home_feed"
    println("the url is $url")
    val request = Request.Builder().url(url).build()
    val client = OkHttpClient()

    client.newCall(request).enqueue(object : Callback {
        override fun onResponse(call: Call, response: Response){
            val body = response.body?.string()

            val gson = GsonBuilder().create()

            val weatherinfo: WeatherInfo = gson.fromJson(body, WeatherInfo::class.java)


        }

        override fun onFailure(call: Call, e: IOException) {
            println("Failed to execute request.")
        }
    })
}

Идея состоит в том, чтобы взять пользовательский ввод (город), сделать запрос на получение (чтобы получить информацию о погоде для этого города), используйте gson, чтобы повернуть затем он обращается к полям этого объекта, чтобы поместить его в намерение перейти к новому действию.

Проблема здесь в том, что объект, к которому я хочу получить доступ в onCreate, weatherInfo, создается во время функции Функция onResponse внутри функции fetch Json.

Каков наилучший способ передачи этой информации, чтобы я мог добавить к своему намерению следующую строку intent.putStringExtra("City", weatherInfo.name), чтобы я мог получить к ней доступ в другой деятельности.

Если есть лучшая практика для решения этой ситуации, я был бы рад узнать!

1 Ответ

0 голосов
/ 16 февраля 2020

Вы можете использовать suspendCoroutine, см. https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/suspend-coroutine.html

private fun fetchJson(userSearch: String): WeatherInfo? = suspendCoroutine<WeatherInfo?> { cont ->
    println("Attempting to fetch JSON")

    val url = "https://api.openweathermap.org/data/2.5/weather?q=$userSearch&appid=MY_API_KEY"

    //val url = "https://api.letsbuildthatapp.com/youtube/home_feed"
    println("the url is $url")
    val request = Request.Builder().url(url).build()
    val client = OkHttpClient()

    client.newCall(request).enqueue(object : Callback {
        override fun onResponse(call: Call, response: Response){
            val body = response.body?.string()

            val gson = GsonBuilder().create()

            val weatherinfo: WeatherInfo = gson.fromJson(body, WeatherInfo::class.java)

            cont.resume(weatherinfo)
        }

        override fun onFailure(call: Call, e: IOException) {
            println("Failed to execute request.")
            cont.resume(null)
        }
    })
}

Теперь выборка Json вернет объект WeatherInfo, если вызов был успешным, и ноль, если вызвана onFailure ()

Edit1: Вы также можете использовать Continuation.resumeWithException(e) вместо возобновления с нуля, если вы хотите обрабатывать / распространять исключение вместо Null.

Edit2: см. https://discuss.kotlinlang.org/t/where-is-suspendcoroutine-supposed-to-be-used/11190/2 для получения дополнительной информации об этой топи c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...