I'm calling a function
(non-suspended) from a button click. I want to run a loop in function
using async
coroutine and return last computed value.
My code :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnCount.setOnClickListener {
var result = GlobalScope.async { dummyFoo() }
runBlocking {
Toast.makeText(this@MainActivity, result.await().toString(), Toast.LENGTH_LONG).show()
}
}
}
private fun dummyFoo() : Int {
var result : Int = 0
val waitFor = CoroutineScope(Dispatchers.IO).async {
for (i in 1..20000) {
result++
}
return@async result
}
return result
}
Output :
I'm getting 0 in Toast
.
I want 20000 in Toast
.
How can I make my code to wait until loop completion and result to become 20000
and output it?
You should use await in dummyFoo()
private suspend fun dummyFoo() : Int {
var result : Int = 0
val waitFor = CoroutineScope(Dispatchers.IO).async {
for (i in 1..20000) {
result++
}
return@async result
}
waitFor.await()
return result
}
It seems that you want to launch a CPU-intensive task off the GUI thread and then present the result in GUI. This is a basic use case of coroutines and it's solved as follows:
btnCount.setOnClickListener {
GlobalScope.launch(Dispatchers.Main) {
val result = withContext(Dispatchers.Default) {
dummyFoo()
}
Toast.makeText(this@MainActivity, result.toString(), Toast.LENGTH_LONG).show()
}
}
This goes with the usual warning that you should not launch coroutines in the global scope, instead create a scope for the activity in question. Otherwise these background tasks will hog the CPU even when the user switches away from your app.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With