Emre
Emre

Reputation: 31

Kotlin coroutines why withcontext in coroutinescope?

I just write a code and use async and await for downloading image. But android studio telling me to use withcontext for this. You can see the code below. But there is already one dispatchers.IO in code. Already we are in IO Scope, why we use again withContext? Is this the really good practice? Code just looks weird.

CoroutineScope(Dispatchers.IO).launch {
        val test = withContext(Dispatchers.IO) {
            val link =
                "https://i.pinimg.com/originals/3b/8a/d2/3b8ad2c7b1be2caf24321c852103598a.jpg"
            ImageProgress.downloadImageToBitmap(link, this@MainActivity)
        }

        runOnUiThread {
            Glide.with(this@MainActivity)
                .load(test)
                .into(binding.imageView)
        }
    }

Upvotes: 2

Views: 1279

Answers (2)

Marko Topolnik
Marko Topolnik

Reputation: 200168

This is how your code should look:

GlobalScope.launch(Dispatchers.Main) {
        val test = withContext(Dispatchers.IO) {
            val link = "https://i.pinimg.com/originals[...].jpg"
            ImageProgress.downloadImageToBitmap(link, this@MainActivity)
        }
        Glide.with(this@MainActivity)
             .load(test)
             .into(binding.imageView)
    }

Note I didn't need runOnGuiThread because I specified the Main dispatcher, and then switched temporarily to IO just for the blocking operation.

Finally, you should also avoid GlobalScope in a production application since your code will cause a leak if the blocking IO operation takes a long while, and the user keeps repeating the action that causes the app to make the request.

You should have a way to cleanly cancel the URL fetch.

Upvotes: 3

Tenfour04
Tenfour04

Reputation: 93629

It suggests that because immediately calling await() on a Deferred is a more convoluted way of achieving the same thing as withContext.

After you fix that, the compiler has no warning for the fact that it was all redundant in the first place. You can also remove the withContext wrapped around it, since you are already on the Dispatcher you want to use.

Upvotes: 1

Related Questions