androidkotlin-coroutinescoroutineandroid-toast

Why toasts fired on a coroutine are displayed even when the coroutine is cancelled?


I have an application that displays a lot of Toasts, as a result Toasts are displayed long after the application went on background.

In order to cancel all Toasts when the application is in background, I have implemented a custom class to wrap the calls to Toast.makeText into a single call done on a coroutine. My idea was that when the onPause method of an activity is fired then I could call CoroutineContext.cancel() to cancel all coroutine. By doing so I hoped that all Toast would have been canceled.

class CustomToast  {
    val job  = Job()
    val coroutineContext = Dispatchers.Main + job
    val coroutineScope = CoroutineScope(coroutineContext)

    fun showSuspendToast(context: Context, msg: String) {
        coroutineScope.launch {
            Toast.makeText(context, "FROM CustomTEST | $msg", Toast.LENGTH_LONG).show()
        }
    }

    fun cancelToastCoroutines() {
        coroutineContext.cancelChildren()
    }
}

Obviously it does not work.

Why does it not work? Where is the error in my reasoning?


Solution

  • Toast.makeText is non-blocking. Toasts are queued by the system. Therefore, all the Toast.makeText are long finished when you get onPause. Cancelling the coroutine does nothing because the coroutine isn't doing anything when you cancel it.

    You should add a Log after Toast.makeText, that would visualize to you when the toast are scheduled.