Android services are a vital part of keeping your application running smoothly both in the background and foreground. They’re also liable to produce Application Not Responding (ANR) errors when not properly optimized.
ANRs are a difficult problem to locate and solve, as they can occur across any of the four Android components. In this series, we’re debunking some of the myths that mobile developers have come to know about how ANRs are triggered. Today, we’ll tackle Android services. You can also check out our posts on broadcast receivers and activities.
In this blog, we’ll answer the following questions:
- What are Android services?
- What are the types of services in Android?
- How are ANRs triggered in Android services?
- How can you get better visibility to quickly identify and solve ANRs in Android services?
If you’re struggling to eliminate ANRs in your Android app, our latest eBook can help.
What are Android services?
A service is an application component within Android that has the ability to perform operations in the background without directly interacting with the user. While users directly interact with your app in activities, services play a vital role in everything from keeping an app functioning in the background to running remote processes like fetching data. We’ll examine each type of service below.
What are the types of services in Android?
There are three different types of Android services and they fall into the following categories:
Background services are services that perform operations in the background without notifying the user.
An example of a background service is a music app continuing to play a song in the background while the user multitasks and interacts with different apps.
Foreground services are the services that perform operations in the background but are visible to users.
An example of a foreground service is the active app alerting the user with a push notification once they have reached a benchmark in their journey. Think unlocking an achievement in a mobile game, reaching a step goal in a fitness app, or receiving confirmation that your order has been placed.
Bound services are the servers in a client-server interface. These services allow components to bind to the service itself, send requests, receive responses, and perform interprocess communication (IPC).
An example of a bound service is when a user re-enters their music app that’s been playing an album in the background, after they’ve been playing a mobile game in the foreground. When the user re-enters their music app, the activity binds to the foreground service again to regain control of the music playback.
How are ANRs triggered in Android services?
In this section, we’ll debunk a few common myths about ANRs in Android services.
Myth #1: There is a 5-second threshold for triggering ANRs in Android services
In reality, it’s actually a 10-second threshold for foreground services and a 20-second threshold for background services.
The Android framework will trigger an ANR under the following conditions:
- A foreground service does not call
startForegroundin under 10 seconds.
- A background service does not start or bind in under 20 seconds.
The longer threshold for the background service is caused by their lower priority on the CPU.
Myth #2: The Google Play Console and Firebase Crashlytics provide enough data to solve ANRs
The Google Play Console and Firebase Crashlytics are great free tools many use to improve the performance of their mobile apps. After all, Google owns both and is the one that determines the crash and ANR thresholds your app must meet to qualify for a high ranking in their Play Store. While the data Google provides is free, it’s also frequently insufficient when trying to get to the root cause of an ANR. To illustrate the lack of data these common tools provide, consider the following breakdown:
As shown above, each of these platforms provides a stack trace that’s captured once the ANR is triggered. However, they differ in the type of data collected, when the data is collected, and the Android versions they support.
But the biggest gap in the data Google Play Console and Firebase Crashlytics provide comes from treating ANRs the same way they treat crashes within their platforms. This means developers get a single stack trace that lacks visibility into the variety of initial conditions that could be causing unresponsiveness in their apps.
How can you get better visibility to quickly identify and solve ANRs in Android services?
Unlike traditional event-based monitoring approaches, like Firebase Crashlytics and the Google Play Console, a session-based monitoring solution collects complete technical data about the entire user experience. This approach to monitoring provides mobile teams with more context to address frustrating, critical issues like ANRs. A few examples include:
- Early freeze detection and stack trace capture (as early as 1 second).
- Multiple stack trace captures to understand how code evolves throughout the duration of an ANR.
- ANR grouping by package to surface the worst offenders in both first- and third-party code.
- Flame graphs to quickly highlight the most common code execution paths in aggregate across every ANR stack trace.
To illustrate the power of session-based monitoring, consider the breadth of data available in user and session timelines alone. For example, the image below shows a user timeline including an ANR in the second session.
Digging deeper into the data, the next image shows a detailed timeline of the second session mentioned above. It includes important data such as activities, web views, moments, network calls, and more.
The rich data provided through session-based monitoring offers a level of detail that makes issue resolution fast and easy regardless of the pressure of the moment. You can leverage data like timeline insight into activities and screen taps, alongside early detection of ANRs to find the root cause of your issues.
For example, GOAT was able to achieve a 99.99% crash free rate during the busiest day of the year by leveraging the helpful, session-based data pictured above.
You can also inspect flame graphs, which combine multiple ANR stack traces together to visualize the most common code paths that contribute to ANRs.
Solving an ANR with data from the Google Play Console is tedious due to their unhelpful grouping methodology based on the similarity of stack traces. The problem with this methodology is that similar stack traces can relate to different initial conditions. Further, not all ANRs caused by the same underlying issue can be attributed to the same line of code. Relying on such sparse data results in wasted time and effort from your mobile team attempting to solve an ANR without a clear insight into the root cause.
Solving ANRs is difficult. This stems from a lack of insight into the root cause, a lack of knowledge of OS triggers, and an absence of actionable data from commonplace solutions like Firebase Crashlytics and the Google Play Console.
For a deep dive into the root cause of ANRs, check out our latest eBook.
Download “Solving ANRs 101: Diving into the Android Framework” today and go to school on:
- How the Android framework measures and triggers ANRS for Android components.
- The limitations of the Google Play Console and Crashlytics when monitoring ANRs.
- How session-based monitoring helps identify and eliminate ANRs.