Hi gusys. I have a question related to coroutine. ...
# android
s
Hi gusys. I have a question related to coroutine. Coroutine block can update the UI after activity finished? If tries to update, crash happens?
c
It depends which thread the coroutine is running on. Only the main thread is allowed to edit the UI.
d
More so, is there something specific you want to achieve? Why do you want to update the UI since the activity has finished?
m
The answers to all the questions are yes depending on what you do. But the practical solution is to launch the coroutine using
lifecycleScope
and then the answer to the first question becomes no, and the others don't matter.
s
I have tried this and found no issue while updating the UI. Actually activity is finished and trying to update UI should create leaking rt? Consider the case of our AsyncTask, if it tries to update UI after the activity is destroyed. It will give leak. I am trying to understand why in the case of Coroutine it doesn’t crash. If it will be like this, they why should we need to cancel the couroutine in onDestroy() lifecycle callback? Can we leave as it is
@mkrussel I know the case of
lifecycleScope
. The system itself cancel the coroutine if using the
lifecycleScope
.I am asking do we need to cancel the coroutine if its not crashing while trying to update UI.
r
How are you creating your co-routine? Can you paste the sample code.
s
@ritesh Please find the code below
Copy code
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    CoroutineScope(IO).launch {
        val data = async { downloadData() }.await()

        withContext(Main) {
            findViewById<TextView>(R.id.textview).text = data.toString()
        }
    }
}

private suspend fun downloadData(): Int {
    delay(10000)
    return 40000
}
m
You should cancel that to prevent leaking the activity. Not sure what
findViewById
does after destruction. But it would be better to use lifecycleScope.
Copy code
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    lifecycleScope.launch {
        val data = withContext(<http://Dispatcher.IO|Dispatcher.IO>) { downloadData() }
       findViewById<TextView>(R.id.textview).text = data.toString()
    }
}
private suspend fun downloadData(): Int {
    delay(10000)
    return 40000
}
👌 1
Actually if you follow Google's and JetBrains advice, all suspend functions should be main safe, so the
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
should be in
downloadData
.
s
@mkrussel I know all things you are saying. I am asking only question that why its not crashing after the activity is destroyed
You are saying, we need to cancel to prevent leak. why that leak is not happening here. Here I am not canceling 🙂
m
It doesn't crash because you are leaking the Activity. So the object still exists and you can modify it, you just should not do that.
I could also imagine that the behavior of
findViewById
could change with different API levels, so it might work now but not work in the future.
s
Thanks @mkrussel