Using WorkManager in multi-process apps

Ben Weiss
Android Developers
Published in
3 min readJan 27, 2021

--

📝 The recent release of WorkManager 2.5.0 enables easier usage in a multi-process environment and provides several stability improvements.

So if you have an app that manages multiple processes, and you need a robust way to manage background work (no more initialization errors ️️⚠), then this is the release for you.

There are a few changes you’ll need to make to your code, so read on to find out more.

At the end of this article I’ll also list some other behavior changes and newest additions in this version of the WorkManager library.

Introducing: work-multiprocess

The new multiprocess artifact introduces performance gains by unifying job scheduling to a single process. To get started, add it to your app.

Implementation "androidx.work:work-multiprocess:2.5.0"

You can now choose the designated process that WorkManager uses to enqueue WorkRequests, and run its in-process scheduler.

A configuration using Configuration.Provider can look like this.

class MyApplication() : Application(), Configuration.Provider {  override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setDefaultProcessName("com.example:remote")
.build()
}

Note: The parameter on setProcessName requires you to pass the fully qualified process name, consisting of your app’s package name, followed by a colon and then the host’s process name, e.g. com.example:remote.

When using work-multiprocess you also want to use RemoteWorkManager instead of WorkManager to manage your work requests. RemoteWorkManager will always reach out to the designated process to enqueue work for you. This ensures that you don’t accidentally initialize a new WorkManager in the calling process. The In-process scheduler also runs in the same designated process.

Benefits

With WorkManager configured like this and using RemoteWorkManager to schedule your jobs, you can enjoy your work being managed faster and more reliably in your multi-process app. This is because SQLite contention can be vastly reduced (because we no longer rely on file based locks) and job reconciliation across processes won’t be necessary any longer since your app will only have a single WorkManager instance running in a process that you can designate.

Behavior changes 🔀

Job reconciliation

Previously, when ActivityManager couldn’t instantiate the JobService to start a job, that job would get dropped silently because of an underlying bug in the platform. WorkManager now ensures that there is a backing scheduler job for every single WorkRequest when an Application instance is created by reconciling WorkRequest objects with jobs.

Limit internal database growth

We saw that one of the causes of app crashes was that the device ran out of storage. This happened mainly on devices that had low storage in the first place. However, when apps scheduled a lot of work, WorkManager was partially responsible for the device running low on storage.

Completed jobs were recorded in an internal WorkManager database for 7 days by default. This time has been reduced to 1 day, which dramatically reduces the database size.

While we shortened the buffer duration, you can control how long your job should be remembered by using the keepResultsForAtLeast() API.

New testing API ✨

If you’re using ListenableFuture with WorkManager, then testing got easier — the TestListenableWorkerBuilder Kotlin extension now takes in any class extending ListenableWorker, providing you with more flexibility during testing.

Bug fixes 🐛

In addition to new features, this release also contains several bug fixes that improve the stability, reliability, and performance of WorkManager. You can read up on all changes as well as fixed bugs in the release notes.

What you can do to improve WorkManager

Contribute to WorkManager through GitHub 👩‍💻

WorkManager, as well as several other Jetpack libraries, can accept contributions via GitHub.

Alan Viverette wrote a comprehensive blog post about the entire process.

Let us know when something goes wrong 📝

Most of the bugs fixed in the 2.5.0 release came in through input from the public issue tracker.

The best way to create an issue we can fix is by creating an issue we can reproduce. To help us reproduce an issue, we recommend that you use the WorkManager sample or provide your own sample code with instructions in the issue description.

Now is the right time to get to work and manage updating that library version in your app.

--

--