Understanding how Android’s ANR mechanism works at the system level is essential for writing proactively resilient code and for diagnosing failures when they occur. This page covers the internals of howDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/AmolPardeshi99/android-performance-skills/llms.txt
Use this file to discover all available pages before exploring further.
system_server detects and reports ANRs.
0.1 ANR vs SNR — what Android actually monitors
Android draws a hard architectural line between two categories of unresponsiveness:- ANR (Application Not Responding): The application process failed to service a system-dispatched event within a timeout. This is always treated as an application-layer fault. Monitored via the message-scheduling mechanism inside
system_server(AMS / InputDispatcher). - SNR (System Not Responding): The
system_serverprocess itself is unresponsive. Monitored by theWatchdogmechanism that polls key system threads.
0.2 Three architectural ANR types
Android’s ANR subsystem has three distinct detection paths, each owned by a different system component.| ANR class | Who detects | Root trigger |
|---|---|---|
| Component-class | ActivityManagerService (AMS) | Service / Broadcast lifecycle callback not completed within timeout |
| Input-class | InputDispatcher | Touch or key event not consumed within 5 s |
| No-Focused-Window | InputDispatcher + WMS | System cannot find a legal focus window to route events to |
Component-class ANR — the bomb-planting model
When AMS dispatches a cross-process task to your app via Binder (for example,scheduleCreateService), it simultaneously posts a delayed timeout message to its MainHandler. Your app must call back via serviceDoneExecuting() or finishReceiver() before the bomb detonates.
Even if you do the real work on a background thread, any delay in delivering the Binder callback — for example, because the main thread queue is jammed by runOnUiThread calls — will still trigger the ANR. The timeout is measured from the moment AMS sends the cross-process message, not from when your code begins executing.
Input-class ANR — the event pipeline
Input events flow through the following pipeline:InputDispatcher maintains a waitQueue of events that have been dispatched to a window but not yet acknowledged. The 5-second clock starts when the event is pushed into the window’s InputChannel. Timeout detection is event-driven — triggered on new events or periodic heartbeats — not a polling loop.
No-Focused-Window ANR is almost always a system issue. It is caused by abnormal window lifecycle during Activity transitions or when
handleResumeActivity is delayed. App code rarely causes this directly. When diagnosing, look at system_server CPU load, Binder call delays between system services, and WMS logs — not just your app’s thread stack.0.3 ANR circuit-breaker sequence
After a timeout fires, Android executes a fixed three-step response to capture forensic data before presenting the ANR dialog to the user.Scene collection
AMS or
InputDispatcher captures the main thread stack trace, CPU usage snapshot, and memory state, then writes the data to ANR trace files.- Older devices and documentation:
/data/anr/traces.txt - Newer devices and bugreports: per-event files at
/data/anr/anr_*
Resource isolation
The
ProcessRecord scheduling priority is adjusted so that the ANR processing flow can execute even under heavy system load. This prevents the diagnostic pipeline from being starved by the same CPU pressure that caused the ANR.0.4 Android version ANR changes
Android has tightened and refined ANR detection across recent releases. Code that was safe on older API levels may need review when targeting newer ones.| Version | Change |
|---|---|
| Android 11 (API 30) | ApplicationExitInfo API: query historical ANR reasons in-process without requiring a bugreport |
| Android 14 (API 34) | ProcessStateRecord: finer process state tracking; JobService ANRs are now explicit (reported to the app) instead of silent |
| Android 15 (API 35) | Foreground service startForeground() timeout reduced from 5 s to 3 s |