ANR (Application Not Responding) is a system notification in Android that appears when an application fails to respond to input within 5 seconds. Unlike glitches (logic errors without UI blocking) and lags (slowdown without full stop), ANR is a critical failure recorded by the operating system: Android displays a dialog “App Not Responding” with options to close or wait. According to Android Vitals Documentation, apps with an ANR rate above 0.5% get a lower rating in Google Play and may be hidden from recommendations. Diagnostics include analyzing /data/anr/traces.txt, using StrictMode, and profiling the main thread.
Key Takeaways
ANR (Application Not Responding) is a user protection mechanism in Android that triggers when the app stops responding to input. The system tracks event processing time: if BroadcastReceiver does not finish onReceive within 10 seconds, Service does not return from onCreate within 20 seconds, or ContentProvider does not respond within 15 seconds — Android generates an ANR.
When an ANR occurs, Android shows a system dialog on top of all windows: “App Not Responding. Close it or wait?” The user can close the app or wait for it to recover. If ANRs happen frequently, the user uninstalls the app. Google Play considers the ANR rate — the percentage of sessions with ANR — in its ranking algorithms.
iOS has no equivalent of ANR with a system dialog. Instead, Apple uses Watchdog, which terminates the process with exit code 0x8badf00d. The user does not see a dialog — the app simply closes to the home screen. This makes ANR on Android more noticeable to the user but gives the system more diagnostic information.
ANR occurs when the system tracks a timeout for one of four component types. Each component has its own time limit.
BroadcastReceiver runs on the main thread. If onReceive starts a synchronous network request, a long database write, or waits for a lock — an ANR occurs within 10 seconds. Solution: use goAsync() and WorkManager for background processing. A typical scenario is receiving a Push notification from FCM and synchronously saving to Room.
Service.onCreate and Service.onStartCommand have a 20-second limit. If the service starts heavy initialization (loading libraries, reading config from the network) on the main thread — ANR is inevitable. Use IntentService (deprecated) or WorkManager for guaranteed background execution.
ContentProvider.onCreate runs before Application.onCreate and has a 15-second limit. If the provider performs a database migration, loads dictionaries, or initializes SDK from the network — this causes ANR at app startup. Solution: lazy initialization, offloading heavy operations to WorkManager.
Android provides several tools for ANR analysis: from system logs to specialized libraries.
On each ANR, Android saves the file /data/anr/traces.txt with a stack dump of all app threads. Find the “main” thread — the last method in the stack indicates the cause. Typical patterns: Thread.sleep(), InputStream.read(), BinderProxy.transact(). To extract the file from the device, use adb with superuser privileges.
Firebase Crashlytics automatically collects ANRs and shows them in the dashboard with traces. For Android 11+, ANR reports come with the full main thread stack. Integration requires adding a dependency and initializing FirebaseApp in Application.onCreate.
CPU Profiler in Android Studio lets you record app traces and see which methods consume CPU time. Enable “Record with method traces” and reproduce the scenario that causes the ANR. The timeline will show which methods were running on the main thread at the time of the freeze.
Example of integrating Firebase Crashlytics for ANR collection on Android:
class App : Application() {
override fun onCreate() {
super.onCreate()
FirebaseApp.initializeApp(this)
FirebaseCrashlytics.getInstance()
.setCrashlyticsCollectionEnabled(true)
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build())
}
}
Fixing ANR primarily means moving all long-running operations from the main thread to background threads. Let’s look at specific techniques for each component type.
WorkManager is Google’s recommended solution for background work. It guarantees task execution on a background thread considering the device state. Unlike Service, WorkManager does not block the main thread and is resilient to app restarts. For BroadcastReceiver, use goAsync() and pass the PendingResult to WorkManager.
Run all network requests, database operations, and file I/O with Dispatchers.IO. The main thread should only update the UI. Use viewModelScope for automatic coroutine cancellation when the Activity is destroyed. Avoid runBlocking() in any context — it synchronously blocks the current thread.
If ContentProvider performs slow initialization, use a lazy loading mechanism: create a provider that returns data immediately and launch heavy initialization through WorkManager with a delay. This prevents ANR at app startup, when the system is most sensitive to delays.
Example of properly using BroadcastReceiver with goAsync in Android:
class FcmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val pendingResult = goAsync()
WorkManager.getInstance(context!!)
.enqueue(OneTimeWorkRequest.from(NotificationWorker::class.java))
pendingResult.finish()
}
}
The best way to fight ANR is to prevent them during development through tools and architectural decisions.
StrictMode with enabled policies detectNetwork() and detectDiskReads()/detectDiskWrites() identifies potential ANRs during development. In Debug builds, set penaltyDeath — any violation will cause an immediate crash, and the developer will see the problem before committing.
Firebase Performance tracks the execution time of key operations and shows which scenarios exceed the ANR threshold. Set custom traces for each screen and network request. If execution time exceeds 3 seconds — it’s a potential ANR requiring optimization.
Simulate slow conditions: limit network speed using Network Link Conditioner on iOS or Android Emulator. Slow down disk reads by emulating slow memory. ANR often manifest precisely in such conditions; on fast developer devices they are invisible.
Frequently Asked Questions
Android explicitly tracks event processing time on the main thread and shows an ANR dialog. iOS uses Watchdog, which forcefully closes the app when it freezes for more than 10–20 seconds. ANR is a feature of Android architecture where several components (BroadcastReceiver, Service) have strict timeouts.
On Android 11+, you can get the ANR dump via adb shell dumpsys dropbox --print data_app_anr. On Android 10 and below, without root access to /data/anr/traces.txt. Use Firebase Crashlytics — it collects ANR reports automatically for Android 11+.
Google Play recommends an ANR rate below 0.5% — no more than 5 ANRs per 1000 sessions. An app with a rate above 1% receives a warning in Google Play Console and may be hidden from recommendations. Ideally, the ANR rate should be below 0.1%.
A coroutine itself does not block the thread. But if inside a coroutine you run runBlocking on the main thread or the coroutine is launched with Dispatchers.Main and performs a long CPU operation — this will cause ANR. Use Dispatchers.IO for I/O and Dispatchers.Default for computations.
Use Android Emulator with a “Slow Network” profile or write a test that calls Thread.sleep(6000) on the main thread. Launch the app through Debug and after 5 seconds you will see the ANR dialog. Check that logcat shows an ANR record with a trace.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also