JustMeh
JustMeh

Reputation: 163

Accessing class variables from a Kotlin coroutine

I've encountered an odd issue here(new to Kotlin and coroutines). I am modifying a class variable in the function getMovies. In the launch block I get a JSON which I then run through GSON and get a mutable list of movie info entries. You can see 2 longToasts from Anko which displays a Toast, but the first one displays 20 and the other one 0. Why is that? Android Studio doesn't throw any errors and I am referencing the same moviesList variable. I tried numerous blogs and instructions on the Internet, but couldn't find anything useful. Any help would be super appreciated!

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())
    }
}

Upvotes: 4

Views: 2810

Answers (1)

Marko Topolnik
Marko Topolnik

Reputation: 200138

The code you have is written against the experimental coroutines API, so let me first upgrade it to Kotlin 1.3 and fix some obvious mistakes:

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()
    }
}

Now, looking at your code, this is what I expect it to do:

  1. launch a concurrent coroutine that will eventually fetch some JSON data from the network
  2. Request to display the "Immediate size" toast
  3. JSON results arrive
  4. Populate the movie list
  5. Request to display the "Size after fetching" toast

The exact details of when you see a toast on the screen can vary and depends on Android's policies and the speed of your fetch.

Upvotes: 3

Related Questions