Skip to content

How to Fix Android ANR (Application Not Responding)

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about How to Fix Android ANR (Application Not Responding). We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Problem

Your app freezes and shows:

ANR in com.example.app (com.example.app/.MainActivity)

Reason: Input dispatching timed out (Waiting to send key event
because the touched window is not responding)

Or:

Reason: Executing service com.example/.MyService

The app's main thread is blocked for more than 5 seconds (input) or 200 seconds (background service).

Quick Fix

Step 1: Find the culprit with StrictMode

// Enable StrictMode in Application.onCreate
if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(
        StrictMode.ThreadPolicy.Builder()
            .detectDiskReads()
            .detectDiskWrites()
            .detectNetwork()
            .penaltyLog()
            .build()
    )
}

StrictMode logs a stack trace every time the main thread does disk I/O or network access.

Step 2: Move network calls off the main thread

// Wrong - network on main thread
val result = URL("https://api.example.com").readText()

// Right - use coroutine
lifecycleScope.launch(Dispatchers.IO) {
    val result = withContext(Dispatchers.IO) {
        URL("https://api.example.com").readText()
    }
    withContext(Dispatchers.Main) {
        textView.text = result
    }
}

Step 3: Move database operations off the main thread

// Wrong - Room query on main thread
val user = db.userDao().getUserSync(42)

// Right - Room supports suspend functions
viewModelScope.launch {
    val user = withContext(Dispatchers.IO) {
        db.userDao().getUser(42)
    }
}

Room blocks the calling thread if you use synchronous DAO methods without a suspend prefix.

Step 4: Avoid large Bitmap decoding on the main thread

// Wrong
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.large_image)

// Right - use Glide or Coil which handle threading
Glide.with(this).load(R.drawable.large_image).into(imageView)

Step 5: Check for deadlocks

// Wrong - main thread waiting for background thread that waits for main thread
synchronized(lockA) {
    runOnUiThread {
        synchronized(lockB) { }
    }
}

Use Thread dumps to diagnose deadlocks:

adb shell kill -3 <pid>
adb pull /data/anr/traces.txt

Step 6: Reduce work in onCreate and onResume

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Defer heavy work
    Handler(Looper.getMainLooper()).post {
        performHeavySetup()
    }
}

Step 7: Use WorkManager for background tasks

// Instead of a Service on the main thread
val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
    .build()
WorkManager.getInstance(this).enqueue(workRequest)

Prevention

  • Never do network, disk, or database operations on the main thread.
  • Enable StrictMode in debug builds.
  • Use lifecycleScope, viewModelScope, or coroutines for async work.
  • Keep onCreate, onResume, and onBind lightweight.

Common Mistakes with crash anr

  1. Forgetting deriving (Show, Eq) on custom data types needed for debugging
  2. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  3. Using head and tail instead of pattern matching, causing runtime errors on empty lists

These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What is the difference between ANR and a crash?

An ANR means the app is unresponsive but still running. A crash means the Process terminated. ANRs appear as a dialog, crashes as a force close.

How long before an ANR is triggered?

5 seconds for input dispatching, 10 seconds for BroadcastReceiver, 200 seconds for foreground services.

Can ANR occur on background threads?

No. ANR only applies to the main (UI) thread. But a background thread that holds a lock the main thread needs can cause an ANR (indirectly).

DodaTech Tool Reference

Doda Browser's Performance Profiler captures frame render times and main-thread stalls, helping identify the exact code path causing ANRs before they happen in production.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro