AI-powered crash analysis is now available on all plans — including Free.Read the crash analysis guide

Android ANR Detection and Prevention (2026)

NFNourin Mahfuj Finick··

Every Android developer has seen it: the app freezes, a dialog pops up saying "App isn't responding," and the user has to choose between waiting and force-closing. That's an Android ANR (Application Not Responding) error, and in 2026, it's more costly than ever. Google Play's policy enforcement around ANR rates means that apps exceeding threshold limits risk being demoted or removed from the store Google Play Developer Policy. This guide covers Android ANR detection and prevention — from understanding what causes them to deploying production-grade monitoring that catches issues before users do.

What Exactly Is an Android ANR?

An ANR (Application Not Responding) triggers when the Android system detects that your app's main (UI) thread has been blocked for too long. Unlike a crash — where the process terminates — the app remains alive but unresponsive, forcing the user to manually intervene. Google defines specific timeout thresholds for different scenarios:

Component Timeout
Input dispatch (key press, touch) 5 seconds
BroadcastReceiver (foreground) 10 seconds
BroadcastReceiver (background) 60 seconds
Service execution 20 seconds
ContentProvider publish 10 seconds

Source: Android Developers — ANRs

When a timeout occurs, Android writes a trace.txt file to /data/anr/ containing thread stack dumps. Parsing these dumps is the first step in any Android ANR detection workflow.

Why ANRs Matter More in 2026

Google's stance on app responsiveness has hardened. Starting in 2023, Google Play began using ANR rates as a key quality signal for app search ranking and discoverability Android Developers Blog. In 2026, the threshold for "bad behavior" has tightened. Apps with ANR rates above 0.5% across all sessions face:

  • Reduced visibility in Play Store search results
  • Warning labels on your store listing
  • Potential removal from recommended app collections
  • Higher uninstall rates — studies show 71% of users uninstall apps due to freezes or crashes Dzone

For serious production debugging, combining traditional ANR detection tools with session replay gives you the full picture. BugsPulse offers privacy-first Android ANR monitoring with zero-PII session replay — letting you see exactly what the user was doing when the ANR struck, without collecting sensitive data. Learn more at bugspulse.com

Common Causes of ANRs

Understanding root causes is essential before you can prevent them. Here are the most frequent ANR culprits in 2026:

1. Main Thread Blocking

The #1 cause. Any long-running operation on the UI thread — network calls, database queries, large file I/O, complex bitmap processing — will trigger an ANR if it exceeds the 5-second input dispatch timeout.

2. BroadcastReceiver Overwork

A BroadcastReceiver running on the main thread has only 10 seconds to complete its onReceive() method. Common mistakes include starting long background operations directly from the receiver instead of delegating to a Service or WorkManager.

3. ContentProvider Initialization

If your app uses a ContentProvider (many SDKs and libraries do), the onCreate() method must execute within 10 seconds or the system triggers an ANR. This is especially problematic during cold starts when multiple providers initialize sequentially.

4. Synchronous Binder Calls

Blocking the main thread while waiting for a Binder transaction to complete — for example, binding to a remote service synchronously — can cause indirect ANRs that are tricky to diagnose.

5. Layout Inflation and Measurement

Complex, deeply nested XML layouts can take significant time to measure and draw on the main thread. Jetpack Compose mitigates this, but poorly written Compose layouts (e.g., re-composing large subtrees on every frame) can also cause jank and ANRs.

How to Detect ANRs in Production

Robust Android ANR detection requires a multi-layered approach.

Google Play Console — Android Vitals

The simplest starting point. Android Vitals shows your ANR rate, crash rate, and key device metrics. It's free but limited — you get aggregate numbers without deep debugging context Android Vitals.

Firebase Crashlytics

Firebase added native ANR detection in 2021. It captures ANR events with stack traces and groups them by similarity. However, it lacks session-level context — you can't see what the user did leading up to the ANR.

BugsPulse — Privacy-First ANR Monitoring

BugsPulse takes ANR detection further by combining real-time ANR alerts with session replay that respects user privacy. Instead of raw PII, BugsPulse captures anonymized UI state, navigation paths, and breadcrumbs — so you can reproduce the ANR context without GDPR/CCPA violations. Check our Flutter crash reporting guide for a related take on mobile error tracking.

Custom ANR Detection (API 30+)

Android 11 (API 30) introduced ApplicationExitInfo with REASON_ANR, letting you detect ANRs programmatically:

val exitReasons = (context.getSystemService(ActivityManager::class.java))
    ?.applicationExitInfoList
exitReasons?.filter { it.reason == ApplicationExitInfo.REASON_ANR }
    ?.forEach { anrInfo ->
        Log.d("ANR", "ANR at ${anrInfo.timestamp}")
        anrInfo.traceInputStream?.bufferedReader()?.use {
            Log.d("ANR-TRACE", it.readText())
        }
    }

Third-Party Libraries

The open-source ANR-WatchDog library has been a staple for years. It runs a watchdog thread that checks if the main thread is responsive every N seconds. If the tick isn't picked up, it logs a custom stack trace. However, it's a separate library to maintain and may not capture system-level ANRs triggered by broadcast timeouts.

Debugging ANRs: From trace.txt to Root Cause

Once you've detected an ANR, the next step is diagnosis. Here's a repeatable workflow:

  1. Collect the trace.txt — On production devices, trace.txt files are dumped to /data/anr/ but aren't accessible without root. Use BugsPulse or Firebase to capture them programmatically via ApplicationExitInfo.

  2. Identify the main thread — Look for a thread named "main" with state SUSPENDED, MONITOR, or WAIT. The stack trace will show where it was blocked.

  3. Find the lock contention — If the main thread is blocked on a monitor entry, find which thread holds the lock. This often reveals a background thread synchronizing on a shared object.

  4. Check I/O operations — Look for FileInputStream, SQLiteDatabase, or OkHttp calls in the main thread trace. These are signs of blocking I/O that should be offloaded.

  5. Review broadcast timing — Check if the ANR timestamp coincides with a BroadcastReceiver execution period. The trace will often include the specific broadcast action that triggered the timeout.

ANR Prevention Best Practices for 2026

Offload Work from the Main Thread

Use Kotlin coroutines with Dispatchers.IO or Dispatchers.Default for any operation that might take more than a few milliseconds:

scope.launch(Dispatchers.IO) {
    val data = database.query(...)
    withContext(Dispatchers.Main) {
        updateUI(data)
    }
}

Use StrictMode in Development

Android's StrictMode catches main thread violations during development. Enable it in your Application.onCreate():

if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(
        StrictMode.ThreadPolicy.Builder()
            .detectDiskReads()
            .detectDiskWrites()
            .detectNetwork()
            .penaltyLog()
            .penaltyDeath()
            .build()
    )
}

Replace AsyncTask with Coroutines or WorkManager

AsyncTask was deprecated in Android 11. Migrate to Kotlin coroutines for in-process async work and WorkManager for deferrable background tasks Android WorkManager Guide.

Optimize Layout Performance

  • Use ConstraintLayout to flatten deep view hierarchies
  • Use ViewStub for rarely-visible UI sections
  • Profile with Layout Inspector in Android Studio
  • Consider migrating to Jetpack Compose for more efficient recomposition

Limit BroadcastReceiver Work

Never perform more than a few milliseconds of work in onReceive(). Use goAsync() if you need to give the main thread a brief break, or delegate to a JobIntentService:

override fun onReceive(context: Context, intent: Intent) {
    val pendingResult = goAsync()
    thread {
        try {
            // Do background work
        } finally {
            pendingResult.finish()
        }
    }
}

Watch ContentProvider Initialization

If your ANRs happen at app startup, suspect ContentProvider initialization. Profile with adb shell am start-activity -W to measure cold start time, and check if any third-party SDK's provider is taking too long.

Setting Up ANR Monitoring in Production

The best defense against ANRs is real-time production monitoring. Here's what to look for in an Android ANR detection solution:

  • Real-time ANR alerts — immediate notification when ANR rates spike
  • Stack trace grouping — automatic grouping of identical ANRs so you can prioritize by frequency
  • Session replay — replay the user's session leading up to the ANR (anonymized for privacy compliance)
  • Device/OS filtering — identify if ANRs are limited to specific Android versions, manufacturers, or API levels
  • Trend analysis — track ANR rate over time to measure the impact of fixes

BugsPulse delivers all of this with a privacy-first architecture. No PII is ever collected, stored, or transmitted, making it suitable for healthtech, fintech, and EU-based apps that must comply with GDPR, HIPAA, or CCPA BugsPulse Privacy Features.

Conclusion

Android ANR errors are more than a user experience nuisance — in 2026, they directly impact your app's visibility on Google Play, your user retention, and your development team's on-call wellbeing. Effective Android ANR detection requires a combination of understanding system timeouts, implementing proper main-thread hygiene, and deploying production monitoring that gives you actionable debugging context.

Start by auditing your app with StrictMode, then instrument your production builds with a monitoring tool that captures stack traces and session context. With BugsPulse, you get real-time ANR alerts, automated trace collection, and privacy-safe session replay — all without storing a single byte of personally identifiable information.

Sign up for BugsPulse today and start catching Android ANRs before they reach your users.