Hello, my name is Amith.
I’m an engineering lead on the Android Framework team.
And I’m joined today by my colleague Makoto to tell you
how to build effective background tasks on Android.
The average Android device has dozens of apps trying to get the user’s attention.
The attention requested needs to add value to the user,
and not just be a distraction.
And just as the user has a limited attention span,
the phone has a limited amount of resources that can be consumed
before it runs out of battery.
With the number of exciting applications growing in the Play Store,
it’s important to balance the needs of all these apps
and ensure that they provide the best user experience,
without sacrificing user happiness.
Let’s talk about foreground services
to understand their place in performing background tasks
and what's changing in Android 12 to help with that.
As far as the user is concerned, an app is in the foreground
when it is showing UI or doing user-perceptible work.
When an app is doing work in the background, the user should have no idea.
Foreground services falls somewhere in between.
In some cases, such as navigation or music playback, the user should be aware
and associate the notification with something they perceive as foreground.
But an application that show the notification that is not adding any value to the user
belongs in the background category.
Foreground services are used to convey to the user that an app
is continuing to provide them a service that they might interact with.
They allow the user to multitask, such as listening to music while browsing the web.
And they allow apps to complete user-initiated tasks at a high priority,
such as sending out a large-attachment email you just composed
or finishing up the HDR processing for a series of photos that you just took.
Foreground services are not meant for tasks that aren't urgent
or for work that the user doesn't need to be aware of.
They also should not be used as a way for an app to stay resident
in memory for the wrong reasons.
Sure, they’re convenient and reliable, but they’re not user-friendly
when the user can't get rid of them.
And guess what some users do with such apps?
They either turn off notifications for the app or uninstall it.
There are several articles online that talk about persistent notifications
and how to get rid of them.
They can be distracting, especially when their notification pops up suddenly
out of the blue in your status bar
and then disappears before you even get a chance to see what was going on.
Foreground services can consume valuable resources
when used incorrectly, draining the battery and holding up precious memory.
And since the app decides when to start a foreground service
and how long it runs,
the OS can't prioritize competing tasks effectively.
This could mean that what's most important to the user may not be completed
in a timely manner or in the most efficient way.
We’ve looked at foreground services in depth and found some very interesting statistics.
We discovered that a user experiences anywhere between 200 and over 500
foreground service notifications per day.
And we found that almost half of foreground services are started from the background
when the user isn’t interacting with the app and isn't expecting the app to be active.
We then measure the duration of foreground service sessions.
Almost 70% of foreground services run for less than 10 seconds.
Some are apps finishing up work on being backgrounded,
and some are happening due to a background trigger.
We also noticed that most sessions are less than two minutes in duration.
After looking at all this data, we came up with a solution
and baked it into Android 12.
Firstly, we're limiting the situations
in which foreground services can be started from the background.
This is applicable to apps targeting API level 31 or newer.
We'll go into a bit more detail later.
We also know that there are valid use cases
that justified the use of foreground services.
That’s why we’re providing APIs to increase reliability of urgent tasks
as well as carving out some specific exemptions
for cases where foreground services may still be the right option.
Secondly, to address the really sharp foreground services
that flicker and distract the user, in some cases, we defer showing
the foreground service notification for 10 seconds.
If the service is done by then, the notification isn’t shown.
Any longer than that, and the notification will be displayed to the user.
The app can override this behavior by specifying its preference
to defer or show immediately.
For all other short background tasks that need to be executed as soon as possible,
we are introducing expedited jobs.
These are low-latency jobs that can be invoked
from either foreground or background to be executed immediately.
The OS will do its best to run them quickly,
but in order to give that same low latency to other contending expedited jobs,
the maximum allocated job duration will be shorter,
of the order of a couple of minutes,
so that apps can get a chance to execute high-priority background tasks
as soon as possible.
Expedited jobs can be run during Doze and Battery Saver modes as well,
similar to foreground services.
This addresses the reliability concern.
With the OS taking over scheduling and execution,
expedited jobs are also subject to Standby buckets.
This means that less frequently-used apps will get fewer opportunities
to run these jobs from the background. The expedited job API is available
through WorkManager as well since version 2.7.
We recommend using WorkManager for expedited jobs wherever possible
since the library is unbundled from the OS, which makes it faster to supply updates
and easier for you to react to future changes without having to deal
with different Android versions yourself.
With the foundational changes to foreground services and expedited jobs laid out,
let’s take the stream to Makoto.
Hi, I’m Makoto Onuki on the Android Framework team.
With foreground services becoming more restricted with Android 12,
there are all sorts of exemptions that remain available to you.
First, when your app is visible to the user,
you can start a foreground service, as your app is in the foreground already.
This is the same as the background activity loans restriction
we introduced Android 10.
This foreground service can remain running
when your app is put in the background afterwards.
You can also start a foreground service on other user interactions
such as a tap on the notification or launch our widget.
In other words, you can start our foreground service as a direct response
to a user interaction with your app.
We exempt certain system broadcasts and callbacks as well.
For example, the broadcasts BOOT_COMPLETED and MY_PACKAGE_REPLACED
will allow you to start a foreground service.
There are also exempted callbacks too.
For example, geofencing callbacks and high-priority FCM messages
are still allowed to start a foreground service.
There are more exemptions.
Please refer to the documentation linked below for the complete picture.
Now, let's take a look at the few app use cases
and talk about what API is best use for them.
For a foreground service that the user starts from the UI,
a foreground service is still the right thing to use.
For example navigation, music players,
and fitness trackers should still use a foreground service
in order to continue the process in the background.
When an email app needs to send a large attachment,
starting a foreground service from the UI is also the right way.
This way, the attachment can be uploaded,
and the email is sent in the background right away,
and the user can move onto doing other things in the meantime.
For most of background work, we recommend using WorkManager.
If your work is time sensitive and will take less than a few minutes,
an expedited job maybe the right choice.
If not, consider using a non-expedited job
which allows the system to schedule it efficiently.
WorkManager is the Jetpack library we recommend using
as your one-stop solution to all background tasks.
With WorkManager, you can schedule expedited jobs,
periodic or opportunistic work.
Many apps use push motifications.
We recommend using Firebase Cloud Messages, or FCM, for push notifications.
Using a high-priority FCM message will allow your app
to receive a push notification, even when the device is dozing.
If your app is a messaging app, put the messages in the FCM payload if possible.
This lets you avoid using a metered network more than needed
and will save a little battery.
If using the payload doesn’t work for you, you can also use an expedited job
to fetch the message from the server.
Please check out our documentation linked below
for more details on the exemptions and the latest guidance.
Now, back to Amith.
Now you should have an idea of how to use the right tools
at the right time for your background work.
We want applications and the operating system to work in harmony helping each other out
in producing a beautiful symphony for the user.
For more information and details about the new requirements for foreground services
and APIs in Android 12, please visit the Developer site linked below.
Thank you.