Common Anr (Application Not Responding) in Iot Apps: Causes and Fixes

In an IoT application the core workflow often looks like this:

January 26, 2026 · 5 min read · Common Issues

What Causes ANR in IoT Apps (Technical Root Causes)

In an IoT application the core workflow often looks like this:

  1. Device‑to‑cloud synchronization – a sensor reading is captured, serialized, and posted to a backend API.
  2. Command dispatch – the app sends a command back to the device (e.g., toggle a smart plug).
  3. State propagation – UI updates reflect the new device state, sometimes after a chain of MQTT messages, HTTP callbacks, and local cache writes.

Any delay in one of these steps can freeze the UI thread, triggering an Application Not Responding (ANR) condition. The most common technical root causes are:

Root CauseWhy It Triggers ANR in IoTTypical Symptom
Long‑running I/O on the main threadSensor callbacks, OTA update checks, or MQTT keep‑alive pings are often placed on the UI thread for simplicity.UI freezes for >5 s on Android; >10 s on iOS.
Heavy JSON parsing / deserializationPayloads from device firmware can be large (e.g., compressed binary blobs) and require CPU‑intensive parsing.UI stalls while the app parses a 500 KB JSON blob.
Database lock contentionLocal SQLite/Room or CoreData stores are used to cache device status. Concurrent writes from multiple background workers can lock the DB for >10 ms.“App isn’t responding” dialog appears when switching between devices quickly.
Network‑related deadlocksRetries with exponential back‑off can accumulate, especially when the device is on a flaky Wi‑Fi or LTE link.Repeated “Network unavailable” dialogs that block the UI.
Third‑party SDK blockingVendor SDKs for sensor fusion, BLE scanning, or camera access sometimes expose callbacks that must be handled on the main thread.Camera preview freezes while scanning for nearby beacons.
Improper use of async APIsDevelopers may call runOnUiThread or dispatch to the main queue incorrectly, inadvertently moving long work onto the UI thread.ANR only when a specific feature (e.g., firmware upload) is used.

In short, any operation that exceeds 5 seconds on Android or 10 seconds on iOS without yielding to the event loop will surface as an ANR. In IoT apps, those operations are often hidden behind “background sync” or “device command” logic, making them easy to miss during code review.

---

Real‑World Impact (User Complaints, Store Ratings, Revenue Loss)

These numbers illustrate why ANR isn’t just a technical nuisance; it directly erodes user trust and bottom‑line performance.

---

How ANR Manifests in IoT Apps – 7 Concrete Examples

  1. Bulk sensor upload freeze – The app receives a batch of 10,000 temperature readings from a weather station and parses them on the UI thread.
  2. Stuck command acknowledgment – After sending a “lock door” command, the UI waits for an MQTT ACK that never arrives; the main thread keeps polling, leading to a timeout.
  3. UI thread blocked by OTA update download – The download progress bar is updated on the main thread while a 150 MB firmware image streams from the cloud.
  4. BLE scan stall – Scanning for nearby devices is performed in onCreate() without a background thread; when many beacons are present, the scan exceeds the 5 s threshold. 5. Local DB write deadlock – Two background workers attempt to write to the same SQLite table simultaneously, causing a lock that lasts >10 ms.
  5. Camera preview freeze during QR code read – The camera feed is processed on the main thread to decode QR codes from a device’s QR‑based setup wizard.
  6. Push notification handling deadlock – A push‑notification handler tries to fetch device status synchronously, causing the notification UI to freeze while waiting for a REST response.

Each scenario can be traced to a specific code path that violates the main‑thread responsiveness contract.

---

Detecting ANR in IoT Apps (Tools, Techniques, What to Look For)

  1. Android Studio Profiler – Record CPU and Network traces while exercising device‑control flows. Look for “Main Thread Blocked” spikes >5 s.
  2. LeakCanary + ANR Monitor – Integrate android.os.StrictMode to catch network I/O on the UI thread. 3. iOS Instruments – Main Thread Checker – Enables runtime detection of UI‑thread violations.
  3. Custom ANR logger – Add a watchdog thread that records timestamps when the UI thread is idle for >5 s; store logs in a remote crash‑reporting endpoint.
  4. Device‑level telemetry – Many IoT platforms expose a “heartbeat” API; correlate heartbeat gaps with UI freeze reports from the client SDK.
  5. Real‑device testing farms – Run automated UI scripts (e.g., Appium) on a matrix of devices with varying network conditions; capture ANR dialogs via UIAutomator.
  6. Performance budgets in CI – Enforce a maximum allowed UI‑thread blocking time (e.g., 3 s) in unit‑test suites using Espresso Idling Resources.

When an ANR occurs, the system typically surfaces a dialog with a stack trace. Capture those stack traces and map them back to the relevant IoT feature (e.g., “firmware upload” or “BLE scan”) for rapid triage.

---

Fixing Each Example (Code‑Level Guidance)

1. Bulk Sensor Upload Freeze


// Bad – parsing on UI thread
listOfSensors.forEach { sensor ->
    val data = gson.fromJson(jsonString, SensorData::class.java) // blocks UI
    updateUi(data)
}

// Good – use AsyncTask or Coroutines
lifecycleScope.launch(Dispatchers.IO) {
    val parsed = jsonString.split("\n")
        .map { gson.fromJson(it, SensorData::class.java) }
    withContext(Dispatchers.Main) {
        displaySensors(parsed)
    }
}

2. Stuck Command Acknowledgment

3. OTA Update Download Blocking UI

4. BLE Scan Stall

5. Local DB Write Deadlock

6. Camera Preview Freeze During QR Decoding

7. Push Notification Handling Deadlock

---

Prevention: Catching ANR Before Release

  1. Static analysis rules – Add a rule in Detekt (Android) or SwiftLint (iOS) to flag any Thread.sleep, ExecutorService.submit without proper Future.get, or direct UI updates from network callbacks.
  2. Performance budgets in CI – Fail the build if a UI trace exceeds the 3‑second threshold.
  3. Canary releases with ANR monitoring – Deploy to a small subset of devices and require zero ANR events in the first 24 hours.
  4. Automated UI‑test suites with timeout assertions – Use Espresso’s onView(withId(R.id button)).perform(click()) combined with `withTimeout(5

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free