首页 > 解决方案 > 从 Kotlin 协程访问类变量

问题描述

我在这里遇到了一个奇怪的问题(Kotlin 和协程的新手)。我正在修改函数 getMovies 中的类变量。在启动块中,我得到一个 JSON,然后我通过 GSON 运行它并得到一个可变的电影信息条目列表。您可以从 Anko 看到 2 个显示 Toast 的 longToast,但第一个显示 20,另一个显示 0。这是为什么呢?Android Studio 不会抛出任何错误,我引用的是同一个 moviesList 变量。我在互联网上尝试了许多博客和说明,但找不到任何有用的东西。任何帮助将不胜感激!

class MainActivity : Activity() {

private var moviesList: MutableList<Movie> = mutableListOf()

fun getMovies() {
        launch(UI){
            val result = async(CommonPool){
                getResponseJSON()
            }.await()
            moviesList = Gson().fromJson(result, MovieDBResponse::class.java).results
            longToast(moviesList.size.toString())
        }
        longToast(moviesList.size.toString())
    }
}

标签: androidkotlinkotlin-coroutines

解决方案


您的代码是针对实验性协程 API 编写的,所以让我先将其升级到 Kotlin 1.3 并修复一些明显的错误:

class MainActivity : Activity(), CoroutineScope {
    override val coroutineContext = Dispatchers.Main + SupervisorJob()

    private val moviesList: MutableList<Movie> = mutableListOf()

    fun getMovies() {
        launch {
            val result = withContext(Dispatchers.IO) { getResponseJSON() }
            moviesList += Gson().fromJson(result, MovieDBResponse::class.java).results
            longToast("Size after fetching: ${moviesList.size}")
        }
        longToast("Immediate size: ${moviesList.size}")
    }

    override fun onDestroy() {
        super.onDestroy()
        coroutineContext[Job]!!.cancel()
    }
}

现在,看看你的代码,这就是我期望它做的事情:

  1. launch一个并发协程,最终将从网络中获取一些 JSON 数据
  2. 请求显示“即时大小”吐司
  3. JSON 结果到达
  4. 填充电影列表
  5. 请求显示“获取后的大小”吐司

当您在屏幕上看到 toast 时,具体细节可能会有所不同,具体取决于 Android 的政策和获取速度。


推荐阅读