无法在Kotlin中更改全局变量值

时间:2019-12-17 20:25:56

标签: android kotlin

我正在更改方法内的全局变量值,并尝试稍后返回。

在FetchData.kt中(称为类)

var homeFeed: HomeFeed? = null     // the variable that needs to be changed 

fun execute() {


    val client = OkHttpClient()
    val url =
        "..."
    val request = Request.Builder().url(url).build()

    val res = client.newCall(request).enqueue(object : Callback {

        override fun onFailure(call: Call, e: IOException) {

            e.printStackTrace()

        }

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

            val ch = response?.body?.string()

            val gson = GsonBuilder().create()
            homeFeed= gson.fromJson(ch, HomeFeed::class.java)  // where the change happens

        }

    })

}

   fun GetData(): HomeFeed? {

       return homeFeed
   } 

在MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

   btn.setOnClickListener {

      val  destination = "destination"

      val places = FetchData(destination)

      places.execute()
      val data = places.GetData()
   }
}

问题在于,将值分配给了 MainActivity 中的“数据”变量,就好像返回的“ homeFeed”变量根本没有改变一样。

调试了代码,以确保api调用不会发生错误,并且变量在方法内进行了更改(但不在其外部!)< / strong>

我真的很坚持,有什么帮助吗?

1 个答案:

答案 0 :(得分:5)

您在发出异步请求后立即调用getData(),因此它没有机会进行更新。异步函数不会立即返回。某些后台线程执行某些操作(网络请求),在这种情况下,将来将来某个时间返回结果时,将调用onResponse

就像按钮上的听众一样。侦听器中的代码不会立即运行,而是在将来用户按下它的某个时间运行。

您的函数可以使用在结果准备好时调用的回调参数来代替使用此成员属性:

fun execute(resultHandler: (HomeFeed) -> Unit) {
    //... snip ...

    client.newCall(request).enqueue(object : Callback {
        // ... snip ...
        override fun onResponse(call: Call, response: Response) {
            val ch = response?.body?.string()
            val gson = GsonBuilder().create()
            resultHandler(gson.fromJson(ch, HomeFeed::class.java))
        }
    })

}

然后,当您调用它时,您会传递一个lambda,当结果准备好时将被调用:

   btn.setOnClickListener {
      val destination = "destination"
      val places = FetchData(destination)
      places.execute { homeFeedData ->
          // Do something with homeFeedData when it arrives
      }
   }