CN

Android ANR Series 1: Understanding Android ANR Design Philosophy

Word count: 2.4kReading time: 15 min
2025/02/08
loading

This is the first article in the Android App ANR series, mainly analyzing the design philosophy of Android ANR from a system perspective. The series directory is as follows:

  1. Android App ANR Series 1: Understanding Android ANR Design Philosophy
  2. Android App ANR Series 2: ANR Analysis Routines and Key Log Introduction
  3. Android App ANR Series 3: ANR Case Sharing

Technical review: 2026-10-14. The original section structure is retained. Implementation details use AOSP android-15.0.0_r1, with Android 11/14/15 API and behavior boundaries called out separately. Default timeouts are not fixed contracts across all OEM devices. This update adds no new device ANR reproductions.

Start by identifying which operation failed to complete, then investigate what delayed it. Android vitals or field monitoring can establish the type and impact. For test devices, combine bugreports, ANR stacks, EventLog, and system/main logs. Older releases commonly used traces.txt; newer reports often contain /data/anr/anr_*, but those directories are not necessarily readable directly on production devices. Perfetto helps only if recording covered the period leading up to the timeout.

1. Universality and Complexity of ANR

An ANR means that an application failed to meet a responsiveness requirement. Expensive main-thread work is one cause; the thread may instead be waiting for a lock or synchronous Binder reply, or remain runnable without enough CPU time. A worker handling a goAsync() broadcast can also fail to complete in time.

A report attributed to an application does not establish that the root cause is entirely in that application. Slow system services or resource pressure can delay it. Conversely, finding Binder or system_server in the evidence does not establish a system bug: follow the actual wait relationship.

  • Application ANR: detects missed completion conditions such as component callbacks or input acknowledgements.
  • System unresponsiveness: sometimes called SNR in engineering discussions. AOSP’s system_server Watchdog checks progress of selected Handler threads and Monitors, not merely whether the process exists. SNR is not a universal classification paired one-to-one with every ANR type. Watchdog source

Much of this monitoring runs outside the application, allowing detection when its main thread is blocked. The monitoring threads can still suffer scheduling delays or lock contention; their deadlines are not hard real-time guarantees.

Detection, diagnostics, a dialog, and process termination are separate stages. There is no universal sequence of killing the app, freezing a complete snapshot, and then asking the user what to do. Some background ANRs are handled silently, and foreground handling depends on recovery, debugging state, and policy. ANR traces primarily contain stacks, not full heap snapshots or an atomic freeze of every thread. Handling source


2. Core Design Philosophy of ANR

Essence of ANR: System-Level Monitoring and Mandatory Intervention

Many detectors can be understood as recording a start condition, awaiting completion, and checking state when a deadline expires. Awaiting completion normally means retaining state and scheduling a check, not blocking AMS’s main thread until the app responds.

Completion differs by operation. Services report completed lifecycle callbacks, broadcasts report finished delivery, and input connections acknowledge processed events. An arbitrary Binder call does not automatically receive a common ANR timer.

For example, Android 15’s IApplicationThread is a oneway interface. After dispatch, work still needs to reach the appropriate app thread. This cannot be explained as synchronous Binder guaranteeing business-operation atomicity. Timeout tracking and synchronous/asynchronous transaction semantics must be examined separately.


Component-Class ANR: Global Protection Logic for Asynchronous Tasks

In Android 15’s ActiveServices, service creation records execution with bumpServiceExecutingLocked() before calling scheduleCreateService(). In the app, ActivityThread.handleCreateService() invokes Service.onCreate() and subsequently reports completion through serviceDoneExecuting(). Creation, starting, and binding have distinct paths; timing only onCreate() is insufficient.

Initialization or earlier main-thread work can consume the execution budget before the service callback runs. Moving long business work to a worker does not justify blocking onCreate() or onStartCommand() while waiting for it. Framework acknowledgement of a lifecycle callback is distinct from completion of the service’s entire workload.

Type Completion being monitored Defaults and version boundary
Execute service Lifecycle callback completion reported by the framework Android 15 AOSP commonly uses short/long execution limits of 20/200 seconds, selected from service execution state; this is separate from promotion to a foreground service
Broadcast receiver onReceive() returns, or PendingResult.finish() completes goAsync() work Through Android 13: normally 10 seconds for foreground-priority broadcasts and 60 otherwise; Android 14+ can extend these to 20/120 seconds under CPU starvation
JobService callback Timely return from onStartJob() / onStopJob() On Android 14+, apps targeting API 34+ receive explicit ANRs for callback response timeouts; this is not the deadline for completing all background work
ContentProvider Timely response to a monitored remote request Startup, Binder threads, or the query itself can be involved; inspect the actual detection configuration rather than applying the input timeout universally

Broadcast foreground priority depends on FLAG_RECEIVER_FOREGROUND and related delivery conditions, not simply on the app having a foreground Activity. goAsync() retains the completion deadline. See the type-specific diagnosis guide and Android 14 JobScheduler change.

ProcessStateRecord holds process-state and OOM-adjustment information and already exists in Android 13. It is not an Android 14 invention for real-time monitoring of every main-thread message. Priority adjustments likewise cannot guarantee that ANR detection and diagnostics execute promptly under all load conditions.

Foreground services have additional, distinct deadlines:

  1. Promotion to foreground: after startForegroundService(), call startForeground() promptly. The troubleshooting guide lists failure to promote as ForegroundServiceDidNotStartInTimeException. It is incorrect to describe a universal Android 15 three-second ANR rule or rely on an unverified persist.sys.fgs_timeout property.
  2. shortService runtime: this Android 14 service type has approximately three minutes of runtime; failing to stop after timeout notification can lead to an ANR. This is a runtime limit in minutes, not a three-second initialization deadline. Service type
  3. Android 15 time-limited services: for apps targeting API 35+, background dataSync and mediaProcessing services each share a per-type budget of six hours in a 24-hour period. Bringing the app to the foreground resets the corresponding timer. Failing to stop after onTimeout() is documented as an internal-exception crash. The crash path in this source baseline is feature-gated, so its presence alone does not prove that every device enables it. Distinguish this from shortService ANRs. Timeout rules

Diagnostics also have limits. Android 11 (API 30) introduced historical exit records through ApplicationExitInfo. This is not a live database of all ANRs: getTimestamp() reports process death time, and getTraceInputStream() can return null after retention buffers overwrite data. An app can recover from an ANR, later exit for another reason, and still have the earlier trace attached. Check the reason, timestamps, and trace contents together.


Input-Class ANR: Dynamic Circuit Breaker System for Event Distribution

EventHub reads device data, InputReader interprets it, and InputDispatcher routes events according to their type and window state. “Circuit breaker” here is a description of timeout handling, not a promise that each timeout immediately kills a process.

  • EventHub uses epoll_wait() to wait for device file-descriptor activity, then reads Linux input_event records with read(). inotify primarily reports device-node creation and removal; it does not carry raw touch data. Blocking waits reduce busy polling but do not guarantee zero CPU consumption. Source
  • InputReader uses InputMappers to interpret device events and generate notification arguments for dispatch. Separate reader and dispatcher threads do not imply lock-free queues. Android 15 exchanges pending data under a lock, then notifies the next listener outside that lock. Source
  • InputDispatcher communicates through InputChannel. Keys require a focused target, while touch normally involves hit testing; not every event is simply sent to the focused window.

InputDispatcher maintains incoming events and per-connection outboundQueue and waitQueue structures. The former holds events awaiting publication; the latter holds delivered events awaiting completion acknowledgement.

Publication records delivery time and a deadline. mAnrTracker tracks outstanding deadlines, and the dispatch loop schedules its next wake-up accordingly. Completion responses advance the queues and tracking state. This is not the generic MonitoredTimeout or fixed-heartbeat mechanism described in the original text. Five seconds is a common default for input response, with actual deadlines affected by window, application, and system configuration.

An app main-thread stall does not automatically stop the reader thread. System-side locks, scheduling delays, and Binder waits can nevertheless affect the overall path. Check receipt, handling, completion, and exactly which acknowledgement the system is waiting for.


No Focused Window Class ANR

No Focused Window is an input-dispatch ANR. In Android 15, an event requiring a focused window can start a wait when a focused application exists but its focused window does not. If neither a focused application nor a focused window exists, the event can instead be dropped; an ANR is not unconditional.

The common default is also five seconds. It is not a faster detector triggered by several consecutive failures to locate a window. The distinction is an unavailable receiving window versus an existing connection that fails to acknowledge an event.

Focus depends on visibility, focusability, display, and window-management state. A new Activity, Dialog, or PopupWindow does not necessarily acquire focus. There is no universal transition requiring an old-window relayoutWindow followed by a new-window addWindow.

Common app-side causes include excessive startup work, a delayed first frame, and FLAG_NOT_FOCUSABLE on the main window. Check Application/Activity initialization, window configuration, and first-frame timing, then investigate WMS, system-server load, and service delays. Official diagnosis

The ANR name alone cannot allocate responsibility to either the app or the system. Use window state and timing evidence to identify the unfinished step.


Unifying Principles of System Design

Four principles follow from these implementations:

  1. Explicit completion conditions: different operations require different acknowledgements; a single “main thread blocked too long” timer cannot describe them all.
  2. Separate detection and execution: the system can detect an app stall, while remaining subject to its own locks and resource constraints.
  3. Separate detection and response: diagnostics, silent handling, dialogs, and termination depend on context. Neither a dialog nor automatic restart is guaranteed.
  4. Asynchronous work retains obligations: worker threads can reduce main-thread load without removing component deadlines or resource contention.

These principles help identify the missing completion condition before assigning every ANR to one kind of stall.

Global Resolution and Active Defense of ANR Problems

Expand investigation from the app to the system when evidence warrants it. A single main-thread stack is a starting point, not a recording of the entire timeout interval.


From Phenomenon to Root Cause: Dissecting ANR Problems Layer by Layer

  1. Establish the event: record ANR type, subject, process, threads, OS version, and time. No dialog does not mean no ANR; ordinary crashes are not automatically ANRs.
  2. Establish the detector: for components, inspect dispatch, callback execution, and completion reporting; for input, inspect windows, connections, and acknowledgements. Both can use asynchronous detection. AMS is not universally a synchronous blocking detector.
  3. Follow waits: inspect the remote thread and reply for synchronous Binder waits, the holder for lock waits, and CPU availability and load for extended Runnable states. Binder pool size and occupancy must be checked for the actual process rather than assumed from one universal constant.
  4. Verify resource causes: CPU, I/O, memory reclamation, or GPU hypotheses need evidence in the relevant interval. CPU out-of-order execution alone does not explain lock contention, and memory-bandwidth pressure does not establish a Binder copy storm.

If the evidence only proves that a thread is waiting, continue investigating what it awaits and when the other side progresses. Keep missing evidence explicitly unknown.


From Passive Response to Active Defense: Three Steps for ANR Governance

  1. Stack analysis: align detection and stack-sampling times. nativePollOnce can reflect recovery, genuine idleness, or message-scheduling problems and must be interpreted by ANR type. Without earlier sampling, existing logs cannot reconstruct every stack from five seconds before and after the event.
  2. Dynamic tracing: record Perfetto ahead of a reproducible scenario and inspect scheduling, Binder, locks, and I/O around the relevant window. Verify enabled sources, coverage, and losses before correlating stack snapshots; nearby timestamps do not prove causality.
  3. Preventive design: shorten main-thread critical paths and avoid long synchronous IPC while holding locks. Bound worker concurrency and queue buildup, and ensure component completion. Executors, HandlerThreads, and coroutines still require protection against pool saturation, main-thread waits, and missing completion reports. Broadcasts or event buses are not universal substitutes for synchronous calls.

Android vitals clustering and ANR Insights can help identify common patterns. A team building rules or machine-learning classifiers should validate labels, false positives, and missed cases, using predictions as investigative leads. The existence of clustering does not establish that Google uses an unpublished “20-plus-indicator” prediction model.

ANR Related Material Sharing

These are historical Chinese-language case studies. Their implementation details should be read in the context of the versions they discuss.

  1. Reflection | Design and Implementation of Android Input System & ANR Mechanism
  2. Xigua Video Stability Governance System Construction 1: Tailor Principle and Practice
  3. Xigua Video Stability Governance System Construction 2: Raphael Principle and Practice
  4. Xigua Video Stability Governance System Construction 3: Sliver Principle and Practice
  5. Xigua Stutter & ANR Optimization Governance and Monitoring System Construction
  6. Toutiao ANR Optimization Practice Series - Design Principle and Influencing Factors
  7. Toutiao ANR Optimization Practice Series - Monitoring Tools and Analysis Ideas
  8. Toutiao ANR Optimization Practice Series - Instance Analysis Collection
  9. Toutiao ANR Optimization Practice Series - Barrier Causes Main Thread Deadlock
  10. Toutiao ANR Optimization Practice Series - Farewell to SharedPreference Waiting
  11. Android ANR | Principle Analysis and Common Cases

References

  1. https://duanqz.github.io/2015-10-12-ANR-Analysis#1-%E6%A6%82%E8%A7%88
  2. https://duanqz.github.io/2015-10-12-ANR-Analysis
  3. http://gityuan.com/2016/12/02/app-not-response/
  4. http://gityuan.com/2017/01/01/input-anr/
  5. https://xiaozhuanlan.com/topic/5097486132

About Me && Blog

Below are personal introduction and related links. I hope to communicate more with everyone in the industry. If three people walk together, there must be one who can be my teacher!

  1. Blogger Personal Introduction: There are personal WeChat and WeChat group links inside.
  2. This Blog Content Navigation: A navigation of personal blog content.
  3. Excellent blog articles organized and collected by individuals - A must-know for Android efficiency optimization: Everyone is welcome to recommend themselves and recommend others (WeChat private chat is fine)
  4. Android Performance Optimization Knowledge Planet: Closed in 2026; retained as a historical introduction.

One person can go faster, a group of people can go further

WeChat Scan

CATALOG
  1. 1. 1. Universality and Complexity of ANR
  2. 2. 2. Core Design Philosophy of ANR
    1. 2.1. Essence of ANR: System-Level Monitoring and Mandatory Intervention
    2. 2.2. Component-Class ANR: Global Protection Logic for Asynchronous Tasks
    3. 2.3. Input-Class ANR: Dynamic Circuit Breaker System for Event Distribution
    4. 2.4. No Focused Window Class ANR
    5. 2.5. Unifying Principles of System Design
  3. 3. Global Resolution and Active Defense of ANR Problems
    1. 3.1. From Phenomenon to Root Cause: Dissecting ANR Problems Layer by Layer
    2. 3.2. From Passive Response to Active Defense: Three Steps for ANR Governance
  4. 4. ANR Related Material Sharing
  5. 5. References
  6. 6. About Me && Blog