I used to call Toast#show() on the UI thread. Then one day, I received notifications related to an ANR (Application Not Responding) error in one of my Android apps.

Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
at android.os.BinderProxy.transactNative(BinderProxy.java)
at android.os.BinderProxy.transact(BinderProxy.java:605)
at android.view.accessibility.IAccessibilityManager$Stub$Proxy.addClient(IAccessibilityManager.java:1207)
at android.view.accessibility.AccessibilityManager.tryConnectToServiceLocked(AccessibilityManager.java:1804)
at android.view.accessibility.AccessibilityManager.(AccessibilityManager.java:606)
at android.widget.ToastPresenter.(ToastPresenter.java:138)
at android.widget.Toast$TN.(Toast.java:1151)
at android.widget.Toast.(Toast.java:259)
at android.widget.Toast.makeText(Toast.java:891)
at android.widget.Toast.makeText(Toast.java:879)
at net.ashishb.androidmusicplayer.util.UiHelper.showToast(UiHelper.java:111)

Programmers on StackOverflow are confused about whether it is OK to call Toasts on the background threads. Just like me, they think that Toast must be displayed from the UI thread. Even though there is no reason.

As a primer, anything that touches your app’s UI must be accessed via the same UI thread. And that’s because the Android UI toolkit is thread-unsafe by design. Making it thread-safe would have introduced thread locks and similar efficiency issues.

However, Toasts are not part of your app’s UI. The toasts are displayed as a part of the System UI. So, avoid ANRs by calling them on the background thread.