首页 > 解决方案 > 如何将对象从函数传递到android中的oncreate方法

问题描述

嗨,我有以下代码:

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是在fetchJson函数内部的onResponse函数期间创建的。

传递此信息的最佳方式是什么,以便我可以将以下行添加到我的意图中,intent.putStringExtra("City", weatherInfo.name)以便我可以在另一个活动中访问它。

如果有处理这种情况的最佳实践,我将不胜感激!

标签: androidkotlin

解决方案


可以使用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)
        }
    })
}

现在,如果调用成功,则 fetchJson 将返回 WeatherInfo 对象,如果调用 onFailure() 则返回 null

Edit1:Continuation.resumeWithException(e)如果要处理/传播异常而不是 Null,也可以使用而不是使用 null 恢复。

Edit2:有关此主题的更多知识,请参阅https://discuss.kotlinlang.org/t/where-is-suspendcoroutine-supposed-to-be-used/11190/2


推荐阅读