Short answer
It occurs when the app blocks the main thread for more than 5 seconds while interacting with the user or more than 10 seconds in a BroadcastReceiver; its cause is network operations or heavy computation on the UI thread.
Explanation
The Android system monitors the main thread's responsiveness. When the thread is blocked (UI thread blocking), the well-known dialog appears to force the app to close. The causes are diagnosed through the Android Vitals reports in the Google Play Console, which record the main thread's call stack at the moment of the freeze, or through ApplicationExitInfo (API 30+) to get a trace for the latest ANR, or by inspecting the files in /data/anr/ on the development device (pulled through adb bugreport), with StrictMode enabled during development to detect blocking early.
Code example
// Enable StrictMode in development to catch blocking calls on the UI thread immediately:
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
)
}Common mistakes
- Performing large file reads, encryption, or database queries on the main thread.
- A deadlock between the UI thread and background worker threads.