Handle Android Services (Part-1)

With recent Android releases dealing with background Services, it has become more complicated than ever. For android developers there are Five groundbreaking changes:

Memory Basics: Why Android devices have out of memory issue on Mobile Apps due to the heavy load of running Activity/Services

Android kernel was first developed it and it was based on Linux-Kernel. The main difference between Android and all other Linux-Kernel based systems is that Android does not have a thing called “Swap space.”

Swap space in Linux is used when the amount of physical memory (RAM) is full. If the system needs more memory resources and the RAM is full, inactive pages in memory are moved to the swap space. While swap space can help machines with a small amount of RAM, it should not be considered a replacement for more RAM. Swap space is located on hard drives, which have a slower access time than physical memory.

Every process gave its oom_adj score by Activity Manager. It’s a combination of application state (e.g., foreground, background, background with service, etc.). Here is a short example of all oom_adj values:

Background execution limits

Let’s talk about the background execution limitations. Background execution limitations mainly apply to two major components:
>Wake locks


A Service is an application component that can perform long-running operations in the background, and it does not provide a user interface.

So, fundamentally Service is the same thing as the activity but it doesn’t have the UI component in it. So, it doesn’t have to perform smooth animation at 60 fps. That’s why it can run perform any task for a longer period of time than the activity.

Background vs Foreground applications:

To learn background execution changes, we need to know the difference between background and foreground application first.

Rule of thumb, your application will be considered as a foreground service if any of the below three cases are true:

1. Your application has currently visible activity.
2. Your application has foreground service running.
3. Your application is connected to another foreground app by binding the service or by consuming their content providers.

If any of the above scenarios are not true in the current instance, your application is considered to be in the background.

Why do we need to restrict the use of background services?
Whenever your applications run in the background using services, your application consumes two precious resources: 1) Memory and 2) Battery.

These two are limited resources on mobile devices and most of the low to mid-range devices don’t have plenty of memory or battery inside it.

Suppose, if your application is doing some very intensive tasks in the background and using the larger amount of RAM to perform that task, then this will create the very junky user experience, especially if the user is using another resource-intensive app, such as playing a game or watching a video in foreground.

As per the documentation for the started service the best practice is,
When the operation is complete, the service should stop itself.
But, many applications have long-running background services, which basically runs for the infinite time to either maintain the socket connection with the server or monitor some tasks or user activity. These services create battery drain and also they constantly consume memory.

What are the limitations of services starting from Android O?

Starting from Android O, if your application is in the background (check above three conditions), your application is allowed to create and run background services for some minutes.
After some minutes passed, your application will enter the idle stage. When your application entered in the idle stage, the system will stop all the background services just like your service calls Service.stopSelf().
And here comes the fun part…
As I discussed above, the problem of battery drain and memory consumption is mainly caused by started services. To eliminate this, Android O completely prevents the use of the startService() method to start the service. If you call startService() on Android O, you will end up getting IllegalArgumentException.

To handle Background process execution and memory issue Google launches WorkManager.


WorkManager uses an underlying job dispatching service based on the following criteria:

Note: If your app targets Android 10 (API level 29) or above, your FirebaseJobDispatcher and GcmNetworkManager API calls will no longer work on devices running Android Marshmallow (6.0) and above. Follow the migration guides for FirebaseJobDispatcher and GcmNetworkManager for guidance on migrating. Also, see the Unifying Background Task Scheduling on the Android announcement for more information regarding their deprecation.

The WorkManager library has several components:

WorkManager — receives work with arguments & constraints and enqueues it.

Worker — have only one method to implement doWork() which is executed on a background thread. It’s the place where all your background tasks should be done. Try to keep it as simple as possible.

WorkRequest — work request specify which Worker enqueued with what Arguments and what are the Constraints for it (e.g., internet, charging ).

WorkResult — Success, Failure, Retry.

Data — Persistable set of key/value pairs which are passed to/from Worker.

Underneath, the architecture of WorkManager lib will look like this:

Now for the rest points, we will discuss in the second part for Location update Issue, Removing of implicit broadcasts, and Notification channels.




Senior Software Engineer | Android | Java | Kotlin |Xamarin Native Android |Flutter |Go

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Abhishek Srivastava

Senior Software Engineer | Android | Java | Kotlin |Xamarin Native Android |Flutter |Go