Application Not Responding (ANR) is a type of error on Android that occurs when a user is unable to take action in an app for a prolonged period of time. The user is presented with a pop-up window after about 5 seconds asking if they would like to close the app or continue waiting. Understandably, neither of these options are particularly inviting to a user who simply wants to engage with your app. Thus, ANRs create poor user experiences that lead to force quits and app uninstalls, so they are very important to address when you come across them in your applications. In this post, we’ll cover several areas about ANRs:

  • What they are and how they are triggered
  • Why they produce a poor user experience
  • How Google Play Store underreports them
  • How they affect your app store ranking and discoverability
  • And how you can solve them

By the end of this post, you should understand the importance of diagnosing and solving ANRs to improve your user experience and give your app a leg up in acquiring and retaining users.

What ANRs Are and How They Are Triggered

ANRs are the Android OS’s attempt to notify developers and users when an app is suffering from bad performance. There is no analogue on iOS other than the system killing an app for exceeding resource limits. According to the Android Developers guide[1], an ANR will be triggered for your app when one of the following conditions occur:

  • While your activity is in the foreground, your app has not responded to an input event or BroadcastReceiver[2] (such as key press or screen touch events) within 5 seconds.
  • While you do not have an activity in the foreground, your BroadcastReceiver hasn't finished executing within a considerable amount of time.

In this post, we’ll focus on ANRs as they relate to the inability to respond to user input. What they boil down to in this regard is that a user is unable to tap, swipe, scroll, or in any way interact with an application.

ANRs are the result of blocking the application’s main thread. Since on Android the main thread is responsible for updating the UI, when it is blocked, the user is stuck facing a frozen screen.

Here are the three most common ways the main thread can be blocked:

  • Networking or storage - Parsing heavy payloads on the main thread will block the UI. Likewise, the storing or retrieving of data from a database can take a long time and lead to ANRs.
  • Processor-heavy activity - This can be anything that involves a lot of CPU, such as data transforms like sorting, manipulating, or parsing data. It can also be things like processing images or videos.
  • A bug involving looping or recursion - Bad code that runs for too long can block the main thread.

There are other reasons why ANRs can happen that are device-related. For example, if the hardware cannot keep up with the demands of the app, then the duration to complete tasks slows. Thus, even when on the same app version, users might encounter ANRs selectively depending on their devices and OSs.

Why ANRs Produce a Poor User Experience

ANRs present themselves to users as frozen screens and stutters. If you have ever tried to scroll in an app and been unable to or tried to rage tap a button that won’t respond, you have interacted with a blocked main thread.

The problem is that people have little patience for a lack of interactivity. If your app frequently hangs, they:

  • Won’t use it as much.
  • Complain about it in app reviews.
  • Uninstall it and replace it with a competitor’s app.

It’s incredibly important to not rely on crashes alone when monitoring your app. The end-user experience is vital to remain competitive when users can easily switch to an app that offers better performance.

How the Google Play Store Underreports ANRs

Users can opt-in to share usage and diagnostic information about the apps they use to the Google Play Store. If they do, their Android device logs various metrics that Google can share with app developers.

Google only reports ANRs if the user cannot interact with the application for 5 seconds. This is an arbitrary threshold chosen by Google, and your application may suffer from a significant number of ANRs that affect the user experience but do not reach the 5-second limit.

And many users will not wait 5 seconds on a frozen screen before force quitting the app. Developers lose insight into just how long users are willing to tolerate slow parts of their app. What if the vast majority of users choose to quit your app if it is frozen for 3 seconds? You won’t know why you are losing users because you do not have a broad enough coverage of ANR intervals.

In other words, if an app is frozen for 5 seconds, it is probably too far gone and it will not respond again. But the app might hang or freeze for a couple seconds and then recover. What is the user impact of these freezes? What if your app has several short freezes instead of long ones?

ANRs Reduce App Ranking and Discoverability

ANRs are one of the Google Play Store’s four core vitals[3]:

  • Crash rate
  • ANR rate
  • Excessive wakeups
  • Stuck wake locks

Bad behavior in these areas directly affects your ranking and discoverability. This means you risk your app’s positioning in search results and whether it can even be qualified to be featured.

For an app, the ANR threshold is exhibiting at least one ANR in at least 0.47% of its daily sessions. In other words, in a given day, about 99.53% of your app’s sessions cannot have a single 5-second ANR, or you will be penalized by the Google Play Store.

If you want to leverage organic app store traffic, you should closely monitor your ANRs.

How You Can Solve ANRs

The biggest barrier to solving ANRs is discovering them. Developers won’t catch all ANRs in testing because they simply cannot account for all the variables their users experience. And ANRs are not exclusively bugs in code, which makes them impossible to completely eradicate. They can stem from:

  • Starting a library on the main thread (which many libraries require)
  • A CPU-intensive load, like parsing a very complex response from a network request on the main thread
  • Heavy view rendering
  • Expensive database calls or writing to files
  • A user losing network connectivity during a video upload

Preventing ANRs is not as simple as “move everything to a background thread.” If that was the solution, we wouldn’t have ANRs. In reality, developers face a constant struggle between maximizing app performance and minimizing system resource usage. For example, creating background threads and moving data between them and the main thread does have a cost. Also, heavy UI updates might incur lag simply due to hardware constraints on older devices.

If you discover an ANR in testing, you can reproduce it by recording a system trace and viewing the resulting heat map.[4]

But how do you discover ANRs once the app is in production?

  • ANRs don’t always happen in a reliable, repeatable manner.
  • Users might not report them, and if they do, there’s not enough information to reproduce them.
  • ANRs can stem from unpredictable variables in the device and user.

In short, you need tooling in place that shows you when ANRs start, how long they last, if they recover, and if they end in app failure.

Embrace Is the Best Tool for Identifying and Solving ANRs

With Embrace, you discover issues faster with proactive alerting and get the actionable data you need to prioritize and solve them. For example, Embrace starts capturing ANRs as soon as the main thread is blocked for 1 second. We provide data on ANR Intervals (when the app hangs but eventually recovers) as well as ANR Exits (when the user quits the app).

In addition, we capture multiple stack traces during the entire ANR lifecycle so you can gain insight into what code your app was executing and how that evolved during the duration of the ANR. This allows you to better pinpoint the root cause. For example, if the main thread was blocked because of a slow-running event like a network call, that is relatively easy to diagnose.

But if the main thread was blocked while doing heavy processing, the stack trace will constantly change throughout an ANR, making it difficult to know where to investigate if you were only given the final stack trace.

How Embrace Helps Mobile Teams

Embrace is an observability, monitoring, and developer analytics platform built for mobile teams. We are a one-stop shop for your mobile app’s needs, including error debugging and monitoring app performance and feature releases. If you’d like to learn more about Embrace, you can check out our website or visit our docs! Feel free to ask us a question or get right down to it and see the product in action with a live demo.

Or, you can dive right into how we can help your mobile teams:

References:

  1. Android Developers Guide - ANRs
  2. Android Developers Guide - BroadcastReceiver
  3. Android Developers Guide - Vitals
  4. Android Developers Guide - Overview of system tracing