How to make Google’s Work Manager work for you

Ayusch Jain
We’ve moved to freeCodeCamp.org/news
7 min readApr 1, 2019
Image Source: https://ayusch.com

Consider some use cases which we encounter in our daily Android development tasks:

  1. Downloading data files from a remote server for a mobile game.
  2. Downloading files from a server.
  3. Synchronizing data collected on mobile with a back-end service, for example: uploading crash analytics, log files, etc…
  4. Backing up device files to online storage.

What’s common between these use cases?

  • They all are long running tasks.
  • They can be deferred to run on a background thread, while the user interacts with the app. These tasks should not affect the app’s performance.
  • They can also be run even when the user is not interacting with the app.

Performing such asynchronous tasks is very common in modern android applications. Rarely we come across apps that do not interact with any backend service and run completely offline. Hence, keeping this in mind the engineers at Google developed many job scheduling APIs to schedule such tasks on Android such as Services, Alarm Manager, Job Scheduler, GCM Network Manager, Firebase Job Dispatcher, before coming up with their latest (and in my opinion the best) solution: Work Manager.

Work Manager, in my opinion, is by far the best API that Google has come up with for Android in recent years. But first, let’s discuss all the scheduling mechanisms other than the work manager and have a look at their pros and cons. In the end, I’ll explain why Work Manager outperforms most of the existing solutions. Also, I’ll tell you when not to use the Work Manager.

In this article, we’ll be discussing these 4 scheduling mechanisms in order:

  1. Services
  2. Job Scheduler
  3. GCM Network Manager
  4. Firebase Job Dispatcher

So, let’s start!

Services

First up are services. Services have been around since as long as I can remember. They have been the go-to solution for developers for performing long-running tasks such as playing music, downloading files, syncing the data, crunching your Android app’s assets and many more. And although we now know that there are much better, more power efficient ways of doing these tasks, services still very relevant for some use cases such as playing music in the background with a notification in the notification tray.

But for the rest of the use cases, we’ve come a long way, and Android has provided much better APIs than services for such tasks. So, let’s see some of the problems with services:

  • By default, services run on the Main Thread of the application in which they are declared. So, any long-running tasks such as image processing, networking, or MP-3 playback slows down the performance of the app and we start noticing jitters on the UI.
  • You have to use inter-process communication to talk to it, which is slower than if it were in the same process as the client.
  • Debugging is difficult, as you have to attach to a different process.
  • If your service crashes, it crashes independently of the main process. This can also be an advantage at times.
  • For long running tasks, you’ll need to use threads inside services, making the implementation more and more complex.
  • If you forget to stop the service if a task is complete, it can keep running in the background and will drain the battery.

So, while services may be good for tasks such as playing music with notifications, it is not the most suitable solution for long running tasks which can block the main thread such as networking, heavy computation, MP3 playback etc.

Job Schedulers

The job scheduler API was introduced in API level 21. It is efficient for networking tasks and will run in the background if the criteria specified in JobInfo.Builder() are met, such as when the device is charging, idle, connected to internet etc. It will also try to batch these jobs together to save system resources. It also comes with back-off and retry logic if a job fails for some reason.

But it is not suitable for non-deferrable work, such as downloading an asset on button click which should happen right away and not delayed.

The other disadvantage, and the one that bothers most developers, is that it is only supported on API versions 21 and higher. So, it would not work on Android devices running on versions less than 21 which is 15% at this time.

GCM Network Manager

GCM Network Manager comes with all the goodness of Job Scheduler with the additional benefit of backward compatibility. Internally, GCM Network Manager uses Job Scheduler for API version > 21. For versions < 21, it uses Google Play Services’ scheduling engine.

It also has the ability to schedule one-off tasks as well as Periodic Tasks. Hence, it removes the extra task of rescheduling the Job from the developer, required in Job Scheduler.

But it has some demerits:

  • Since it uses the Play Services’ scheduling engine, it will only work on devices with play services installed.
  • When play services are updated, the jobs are wiped out. The developer has to take care of scheduling the job again.
  • Not suitable for non-deferrable tasks or tasks supposed to run at a specific time.
  • Google deprecated GCM on 10th April 2018 and it will be completely removed by 11th April 2019, hence it is advisable to not use GCM Network Manager any further.

Let’s have a look at Firebase Job Dispatcher which solves our problems.

Firebase Job Dispatcher

Firebase Job Dispatcher is an Android library for scheduling background jobs. It supports backward compatibility up to API version 9.

Just like GCM Network Manager, it uses Google Play Services’ scheduling engine to schedule jobs. If the device does not have play services installed, it uses Alarm Manager. For Android devices running API version 21 or higher, it uses Job Scheduler.

So far so good. It manages backward compatibility, runs on devices with no Google Play Services and has one-off as well as periodic tasks.

So, why bother with Work Manager when Firebase Job Dispatcher has it all?

Well because, when these APIs are used incorrectly, it leads to battery drain. So, to save power, Android has released many power saving features such as Doze Mode, Doze on-the-go, limits on background services, App Standby Buckets, etc. So, as a developer, it becomes our responsibility to take advantage of all of these so as to ensure our app remains battery efficient on all API levels.

This means a lot of spaghetti if-else code. So, let me introduce you all to the latest addition to scheduling API in android development:

Work Manager

As I’ve already mentioned, work manager is, according to me, one of the best APIs that Google has released for Android in recent years. It ticks all the boxes you expect from a scheduling API, and has a high level of abstraction so that you don’t have to worry about granular details such as power consumption, handling back-off and rescheduling.

Work Manager is suitable for deferrable, guaranteed background work. The keywords to focus on here are deferrable and guaranteed.

Work Manager in Android will not run your tasks immediately but will differ them to be executed at a point in time when the constraints you mention are met. It also takes into account battery constraints. It also guarantees that the work will be executed even if your device restarts.

Here is a great diagram which outlines when is it perfect to use Work Manager in your Android applications:

Image source: Google

As you can see, it is suited for deferrable tasks which need not run at a precise time in the future like an Alarm or Reminder.

Benefits of using Work Manager:

  • Backward compatible up to API 14
  • Add constraints like networks, charging.
  • Can schedule one-off or periodic tasks.
  • Can chain tasks together.
  • Guarantees execution even if device restarts.
  • Executes tasks at an optimized time in future considering battery, network availability.
  • It is a part of Android Jetpack libraries and is recommended by Google :P

It is suitable for tasks such as sending crash reports to a background service, syncing data with a web service, crunching your app’s assets, etc.

Conclusion

Work Manager, in my opinion, can definitely be used to perform all deferrable tasks in your android app.

But if the task needs to be performed immediately (playing music, downloading a file), you’ll be best off performing it with a foreground service (eg: Playing music and showing a notification to change songs) or Download Manager (for downloading a file).

So, you can now go ahead and audit your code for possible replacements with Work Manager. A good place to start would be all the services that your app creates ;)

The article was originally posted here.

What’s next

In the next post on Work Manager, we’ll be integrating Work Manager in an Android application and have a practical look at how to set up and use Work Manager in Android. So, stay tuned!

*Important*: I’ve created a SLACK workspace for mobile developers where we can share our learnings about everything latest in Tech, especially in Android Development, RxJava, Kotlin, Flutter, and overall mobile development in general.

Click on this link to join the slack workspace. It’s absolutely free!

Like what you read? Don’t forget to share this post on Facebook, Whatsapp, and LinkedIn.

You can follow me on LinkedIn, Quora, Twitter, and Instagram where I answer questions related to Mobile Development, especially Android and Flutter.

--

--