Direct answer
Diagnose an ANR by classifying why Android considered a component unresponsive. Input dispatch, broadcasts, services, providers, and jobs have different triggers and callback boundaries. Timeout behavior depends on event type, platform, device, and system state; Android says AOSP and Pixel examples vary by OEM. No example is a universal deadline for local inference. For input dispatch, inspect the main-thread stack at the event time. Blocking I/O, synchronous binder calls, initialization, and lock waits require different checks. If the UI thread waits for a lock, inspect its owner and wait chain. Moving work off the main thread is not enough if the UI immediately waits for that worker or contends on the same lock. Correlate the ANR signature with reports and available traces. Android recommends Perfetto for main-thread running/runnable state, system_server lock contention, and slow binder replies. Stacks can be incomplete or captured after the cause. Treat signatures as clues and correlate event type, component, process, timestamp, and reproduction steps. ApplicationExitInfo is available from API 30 and can report REASON_ANR and expose a system trace, but it is retrospective, not a live monitor. A recovered ANR trace may be attached to a later process-exit record with a different reason, so correlate process identity and timestamps instead of assigning cause from the exit reason or one stack. getTraceInputStream can return null if the shared circular buffer was overwritten and can throw IOException. Guard by API level; unavailable trace data does not prove no ANR occurred. Separate ANRs from crashes, low-memory kills, initialization failures, and slow but responsive background inference; ApplicationExitInfo has distinct reason codes. A long off-UI task can be a latency concern without an ANR, while a short call can contribute if it blocks input or holds a needed lock. For local AI, map trace frames to the UI callback, model manager, native call, persistence, and return callback. Check whether evidence shows a blocking wait or lock owner; do not infer an ANR from a slow-looking model operation alone. COVE-LIFECYCLE-01 documents ModelManager states and serialized loading, not a Cove ANR incident or trace-collection feature. BENCHMARK-01 says the repository lacks a complete real-device dataset. This is a diagnostic method, not a measured Cove defect or device result. Redact private prompts, transcripts, images, and account data from attachments. After one targeted change, repeat the same interaction on the same build and environment. Preserve the ANR type, process/component, thread evidence, suspected wait owner, and retest. If evidence is missing, mark the cause unconfirmed. Never turn this method into a blanket five-second limit for model tasks.
The model appears ready, but the first tap shows an ANR dialog
A tester opens a local-AI feature whose model was marked ready, taps an action, and sees an ANR dialog. Install and initialization succeeded, but no trace shows whether preprocessing blocked the main thread, a lock owner stalled, or another component caused the delay.
Decision
Capture the ANR type and report, inspect main-thread and lock-owner evidence, and distinguish an ANR from background inference or another process exit before changing threading.
Expected outcome
Record a cause only when a trace or controlled reproduction supports it. If evidence is missing, mark the cause unconfirmed rather than blaming the model.
Evidence to collect
The claim becomes reviewable only when the following evidence is attached to the same artifact and test run:
- Main-thread and task ownership map
- Slow-path fixtures
- Cancellation and responsiveness result
A runtime comparison is publishable only when artifact identity, build configuration, selected backend, task fixture, and failures are recorded.
Implementation workflow
- Classify the trigger. Save ANR subject, component, process, platform, time, and foreground context. Identify the event type because input, receiver, service, provider, and job callbacks have different boundaries.
- Collect reports and exit records. Preserve system or test-generated reports and stacks. On API 30+, inspect ApplicationExitInfo and getTraceInputStream; handle null and IOException, and correlate process/time if a recovered ANR trace appears on a later exit record.
- Inspect stacks and scheduling evidence. Locate blocking I/O, binder, initialization, or lock frames. If the UI thread waits on a lock, inspect its owner. Use Perfetto when available to distinguish running, runnable, blocked, and contended states.
- Map evidence to the local-AI path. Correlate frames with the UI callback, model manager, native call, persistence, and return callback. Treat pool saturation or lock cycles as hypotheses until trace evidence supports them.
- Fix one cause and rerun. Keep the build and reproduction inputs fixed; change only the confirmed blocking or contention edge. Recapture evidence and record unresolved causes as unknown. Redact private content from reports.
Keep each transition observable. A failure should identify the stage, artifact, runtime, and recovery action without logging private user content.
Acceptance criteria
- The report names the ANR type and component and distinguishes ANR evidence from crash, low-memory exit, initialization failure, or a slow background task.
- A proposed root cause is tied to a main-thread stack, lock-owner or scheduling trace, or repeatable controlled reproduction; missing traces remain explicitly unavailable.
- The same recorded user path is rerun after a targeted change, and no universal timeout, Cove incident, trace-collection feature, or performance result is claimed without evidence.
Decision table
| Dimension | Choice or evidence | How to interpret it |
|---|---|---|
| First-screen readiness | Check shell rendering and model prerequisites | Finds startup gaps but does not classify an ANR or blocked thread. |
| Build/runtime triage | Locate the earliest failed stage from packaging through task execution | Separates install and initialization failures; thread evidence is still needed to explain unresponsiveness. |
| ANR diagnosis | Correlate event type, stacks, lock owner, and trace timing | Supports a specific cause when evidence exists; absent traces leave the cause unconfirmed. |
| Long-task policy | Choose asynchronous ownership, progress, and cancellation behavior | Improves task design but is not an ANR timeout or proof that the UI blocked. |
Failure patterns to prevent
- Loading inside composition
- Blocking lifecycle callbacks
Also prevent silent fallback, unpinned artifacts, missing cancellation, and conclusions that combine unlike configurations. Store unsuccessful runs alongside successful ones.
Minimum reproducibility record
| Layer | Record |
|---|---|
| Device | Manufacturer, model, chipset, RAM class, operating-system build |
| Software | Application version and git commit |
| Model | Family, variant, revision, format, file length, hash, quantization |
| Runtime | Name, revision, requested backend, observed backend evidence |
| Workload | Fixture revision, input hash, prompt hash, output policy |
| Outcome | Completed, failed, cancelled, fallback, and privacy-safe diagnostics |
Release checklist
- ☐ The primary query is answered without an unsupported number.
- ☐ Every artifact and runtime is pinned.
- ☐ The representative task and failure policy are explicit.
- ☐ Lifecycle, cancellation, cleanup, and fallback are tested.
- ☐ User-content and network boundaries are documented.
- ☐ Result wording applies only to the recorded configuration.
- ☐ The page links to raw method or evidence when results are added.
Sources and related evidence
- Cove benchmark method
- Android Developers: Diagnose and fix ANRs
- Android Developers: Processes and threads overview
- Android API reference: ApplicationExitInfo
Chinese deployment and troubleshooting content is organized in the .奇连 AI 端侧专题.
Frequently asked questions
Does every Android ANR mean model inference ran too long?
No. ANRs have different component triggers. Inspect the event type and relevant stacks before attributing the cause to inference during that task.
Can ApplicationExitInfo always provide the ANR trace?
No. From API 30 it can expose exit reasons and traces, but the trace may be null or unavailable. Correlate process and time.
Should every model request have a five-second deadline to prevent ANRs?
No. A timeout is not a diagnosis; an asynchronous request can run longer without blocking UI. Use event and trace evidence.
Can an idle main-thread stack prove the app was not responsible?
No. The sync-barrier leak is fixed in Android 17, but Android 16 and earlier can still show the symptom. Check related threads and traces.