GreenRobotLabs Icon GREENROBOTLABS
6 min read

How to Fix ANRs in Android (Step-by-Step)

Learn how to debug and fix Android ANRs using trace analysis, profiling, StrictMode, background work, and production monitoring.

How to Fix ANRs in Android (Step-by-Step)

ANR stands for Application Not Responding. It’s Android’s way of telling you the app has become unresponsive for too long.

ANRs typically happen when the main thread (UI thread) is blocked and can’t respond to user input or system events. Even if your app doesn’t crash, ANRs are just as damaging because users experience them as frozen screens, taps not registering, or scrolling stuck—often ending with the “Wait / Close app” dialog.

This guide explains what causes ANRs, how to debug them properly, and how to eliminate them in production Android apps.

What causes ANRs in Android?

Most ANRs come from one of these categories:

Heavy work on the main thread

Examples include:

  • database queries
  • JSON parsing
  • image decoding
  • file I/O
  • encryption or compression

Locks and thread deadlocks

Examples include:

  • long synchronized blocks
  • UI thread waiting for background tasks
  • database locks under heavy concurrency

Binder or IPC calls that stall

Examples include:

  • slow ContentProvider calls
  • device services or system calls
  • third-party SDK operations

Excessive work during app startup

Startup ANRs often appear when the app does too much inside:

  • Application.onCreate()
  • splash screen initialization
  • dependency injection setup

Step 1: Confirm it’s really an ANR

Not every slow UI is an ANR.

ANR means Android detected your app was unresponsive long enough to trigger a system warning. Users often describe it like this:

“The app froze and Android asked me to close it.”

That’s an ANR.

Step 2: Get the ANR trace

The fastest way to debug ANRs is by reading the trace information.

You can usually find ANR reports in:

  • Android Studio Logcat
  • Google Play Console (Android Vitals)
  • Firebase Crashlytics (if configured)
  • device logs during local testing

The key is the main thread stack trace, which shows what your app was doing when it froze.

Step 3: Read the trace correctly

When you open an ANR trace, focus on these points:

Check the “main” thread first

If the main thread shows a call related to database access, file operations, loops, or blocking work, that’s likely the culprit.

Look for waiting or blocked states

Red flags include:

  • WAITING
  • BLOCKED
  • “waiting to lock…”
  • deadlocks

This usually means the UI thread is waiting for another thread or resource.

Find the deepest call that belongs to your app

Framework calls can create noise. Look for lines that include:

  • your app package name
  • your repositories or DAOs
  • parsing or utility logic

That’s where the fix usually belongs.

Step 4: Reproduce the ANR locally

Reproducing the issue is critical because it allows real fixes instead of guessing.

Ways to reproduce ANRs more reliably:

  • test on low-end devices
  • enable “Don’t keep activities” in Developer Options
  • throttle the network
  • test with large datasets and big file imports

Typical flows to test:

  • cold start app launch
  • opening heavy screens
  • rapid navigation between screens
  • importing or scanning large files

Step 5: Fix the most common ANR patterns

Most ANRs can be eliminated by applying the right fixes in the right place.

Fix 1: Move heavy work off the main thread

If you find any of these on the main thread:

  • database queries
  • JSON parsing
  • reading/writing files
  • cryptography or compression

Move them to background execution using Kotlin Coroutines and IO dispatchers. Your UI should only update state and render, not do heavyweight work.

Fix 2: Room / database ANRs

Room is safe until slow queries happen at the wrong time.

Common causes:

  • huge queries returning large datasets
  • joins producing very large results
  • queries triggered repeatedly during navigation or UI updates

Fix patterns:

  • add indexes for frequently filtered columns
  • use paging for long lists
  • reduce query size and return only needed fields
  • avoid loading large entity graphs when unnecessary

Fix 3: Startup ANRs (Application.onCreate)

Startup ANRs happen when the app freezes before users even see the UI.

Common startup problems:

  • initializing too many SDKs immediately
  • heavy dependency injection setup
  • synchronous access to disk or preferences
  • database access during startup

Fix patterns:

  • delay non-critical SDK initialization
  • defer setup until after the first screen is shown
  • move background tasks into WorkManager when appropriate
  • load non-essential data later

Fix 4: Deadlocks and blocking on background work

A dangerous pattern is when:

  1. UI thread holds a lock
  2. background thread needs the same lock
  3. both wait, and the UI freezes

Fix patterns:

  • reduce synchronized blocks
  • avoid nested locking
  • keep locks short and isolated
  • consider lock-free concurrency where possible

Fix 5: Third-party SDK problems

Some ANRs come from SDKs that:

  • block the UI during initialization
  • do heavy work inside callbacks
  • perform I/O on the main thread

Fix patterns:

  • update the SDK version
  • delay initialization
  • isolate calls behind background execution
  • measure the impact using profiling tools

Step 6: Use StrictMode during development

StrictMode can catch bad patterns early, such as:

  • disk reads on the main thread
  • disk writes on the main thread
  • network calls on the main thread

It’s one of the best tools for preventing ANRs before they reach production.

Step 7: Monitor ANRs in production

ANRs often vary based on:

  • device performance differences
  • Android version behavior
  • memory pressure
  • background services
  • real user data size

Track ANRs using:

  • Google Play Console Android Vitals
  • crash reporting dashboards
  • performance monitoring tools

The best approach is always:

  1. identify the top ANR signature
  2. fix the root cause
  3. confirm the reduction in the next release

ANR Prevention Checklist

  • ✅ Avoid disk and network work on the main thread
  • ✅ Run database operations in background execution
  • ✅ Use paging for long lists and large datasets
  • ✅ Keep startup lightweight and defer non-critical work
  • ✅ Delay heavy SDK initialization
  • ✅ Enable StrictMode in debug builds
  • ✅ Monitor ANRs after every release

FAQ

What is the fastest way to fix ANRs? Start by checking the main thread stack trace in the ANR report. In most cases, it clearly shows what blocked the UI thread.

Can Jetpack Compose cause ANRs? Compose usually causes frame drops and jank rather than ANRs. However, if the UI triggers blocking work like database access or file I/O during rendering, it can still lead to ANRs.

Are ANRs worse than crashes? In many cases, yes. Users experience ANRs as “the app is broken,” and they often uninstall even if the app doesn’t crash.


ANRs are not random. They are almost always caused by blocking work on the UI thread or incorrect concurrency patterns.

Once you build a habit of reading traces, reproducing issues locally, moving heavy work off the main thread, and monitoring production behavior, you can eliminate ANRs and keep your Android app fast and responsive.