In the world of smartphones, Android has always been, uh, generous when it comes to allowing apps to do stuff in the background. This leads to some really powerful apps, but Android's background free-for-all also leads to some apps accidentally (or greedily) sucking down background resources. In the run-up to Android 7.0, Google warned everyone that The Great Background Processing Lockdown was coming, and in Android 8.0, serious background restrictions for apps targeting Android 8.0 (remember, that's a big qualifier) have finally arrived.

Ben Poiesz, a project manager on the Android Framework, laid out the team's rationale for scaling back background processing in a Google I/O 2017 talk. The goal of locking down background processing is not only improve battery life but also to better manage memory so the device runs more smoothly. He said the team wants Android to have "consistent device performance" over time, which was definitely not the case in the past. At the talk, Poiesz showed a few slides of a pre-O device's typical performance deterioration over the first few months. The first chart wasn't surprising, with the takeaway being "more apps = less battery life" thanks to apps doing processing work in the background. The second was a little shocking; Google found that UI performance was also affected by the number of apps installed. As apps on their own schedule randomly start up in the background, they slow down the phone and cause UI animation skips. Even things like uptime would slow the UI performance, presumably from apps claiming system resources and never returning them.

At his talk at I/O, Poiesz said Google's eventual goal is for "multi-day battery life" in Android, which he said would require a "6-8x efficiency improvement" from where Android is today. He described the switch to JobScheduler (see below) as "setting the stage for the future," so in addition to what we're seeing in Oreo, I'd expect more background changes to come to Android eventually.

Mandatory JobScheduler

The change from free-for-all background processing to something more managed has been a steady march. In Android 5.0, Google introduced the JobScheduler API, a "traffic cop" for background tasks in Android. Instead of having an app wake up the phone on its own timeline to perform a background task, apps would put in a request to the JobScheduler. JobScheduler would batch up requests from multiple apps into a coordinated burst of background activity. Batching up background tasks lets the phone stay idle for longer periods of time, which is key to saving battery power. JobScheduler also encourages delaying noncritical background work until the phone is idle, plugged-in, and on Wi-Fi, when the device has unlimited power and data. To save on RAM, JobScheduler runs these jobs one at a time, or a few at a time, so the system doesn't run out of memory. The feature also enabled the "Doze" mode in Android 6.0 and up, and this put an idle phone into a deep sleep to save power.

When JobScheduler was introduced in Android 5.0, it was an optional thing that apps could coordinate with if they wanted to be good citizens. The old system was still around, so apps could also ignore JobScheduler if they chose to do so. In Android 8.0, Job Scheduler has been promoted from optional to the main method of running background tasks for apps that target Android 8.0.

Another periodic reminder: we're talking about changes for apps that "target" Android 8.0, and at launch that's going to be a very small group of apps. For the background processing changes, though, users get a bit more control and can manually force the new background limitations on an app. Just head to the App Info screen (That's System Settings -> Apps & Notification -> App Info -> [App Name] ), tap on "Battery," and turn off the ambiguously-titled "Background Activity" switch. This won't necessarily prevent all background activity, but it will opt any app into the new Oreo background rules. Depending on how the app is written, this might break all background activity for the app, so use with caution.

RIP Implicit Broadcasts

Enlarge/ Google's flowchart for developers, now that background processing isn't allowed in O. Android's "JobScheduler" API is called "JobDispatcher" in this slide because Google loves changing the names of things.

Before JobScheduler, the old app background startup method had apps subscribe to "implicit broadcasts"—system-wide, generalized announcements of status changes, like a new picture being taken or a connectivity change. Multiple apps would listen for one of these status changes, and all start up at once, which could cause a low memory situation as every app tried to load itself at once. This caused major performance issues for devices with low memory, and the situation got worse as you installed more apps. Implicit broadcasts would often trigger when the user was in the middle of doing something, like taking a picture. You take the first picture, a million apps start up because they are subscribed to the "new picture" broadcast, and now when the user is trying to immediately take a second picture, the phone has slowed to a crawl because a bunch of apps want to load themselves into memory.

Google took a gradual approach to fixing implicit broadcasts, shutting down three of the biggest troublemakers in Android 7.0 Nougat—the new picture broadcast, new video, and connectivity change. In Android 8.0, most implicit broadcasts are being disabled for background apps targeting O. If an app is in the foreground, it will be able to receive implicit broadcasts, but apps won't be able to "wake up" anymore from a broadcast. This is yet another change only for apps that target Android 8.0, but users can opt apps into the change by turning off the "Background Activity" switch.

It's worth noting that the other kind of broadcast, an explicit broadcast, can still wake up an app. Explicit broadcasts specifically target an individual app, and these are usually called from notifications (like an incoming message) from within the app itself or called when the app is updated through the Play Store.

Since explicit broadcasts are targeted at a specific app, it's unlikely that this would cause a device slowdown or use a ton of RAM, so they are allowed. For that same reason, some rare or more targeted implicit broadcasts are still allowed, too. Examples include plugging in a headset, changing the locale or timezone, and connecting to Bluetooth. Google doesn't feel such activities are detrimental to the user experience.

No more wakelocks, no silent background services

While JobScheduler and receiving broadcasts both serve to wake up an app, the other component of background processing on Android is keeping the phone awake once your app has started up. In Android parlance, this is a "wakelock"—an single app's ability to keep the phone awake to do processing work.

In past versions this was 100 percent up to app developers. Any single app could keep your phone awake for any reason, and if a single app messed up and didn't release its wakelock, you phone would never go into a low-power state. Moving to these low-power states is absolutely critical for battery life on a smartphone—holding a wakelock can cut hours off a device's battery life. In the world of rooted Android devices, apps and Xposed modules that detect and kill wakelocks are a cottage industry, numerous apps and guides out there let advanced users lockdown background processing themselves.

But Android 8.0 is clamping down on wakelocks—an app's wakelocks will be automatically released by the system when the app is "idle." This basically means that if an app isn't running an activity in the foreground (generating UI that is visible to the user) and isn't using a foreground service (generating an "I'm doing stuff" notification that is visible to the user), the app is going to be shut down. App developers are still expected to manage wakelocks themselves, but this is a "protection" against apps keeping the phone awake.

Enlarge/ Some apps, like Google Maps and Google Music, won't trigger the "Background apps" notification and some will. Tapping the notification will bring up a list that links to the battery stats for each app.

Ron Amadeo

With the death of wakelocks, as Poiesz put it, "free-running background services are no longer 'a thing'" in Android. Apps won't really be able to do anything in the background anymore, which sounds much more limiting than it really is. Apps can still provide ongoing features and services and do everything they used to do in the background, but now the user must be aware of it. Instead of a background service, apps can use a "foreground service." This works just like a background service, but critically, this approach generates a notification, letting the user know that an app is turned on and consuming battery, RAM, and other resources. We see this today with things like Google Maps' bright green navigation notification, a music app's "currently playing" notification, or Uber/Lyft's "your driver is on their way" notification.

Google's mantra of "tell the user about background processing" makes a lot of sense, and it's a standard feature of desktop OSes like Windows (with the system tray) and macOS (with menu bar icons). In Android 8.0, the base OS also has a new system-wide "App is running in the background" notification, which is a single line, collapsed-by-default notification that will list each app running in the background. This notification seems meant to catch the "sneaky" apps that target an old version of Android and can still quietly run in the background, but there is some potential for duplicate entries here, too.

The way the "running in the background" notification works changes from app to app. Media apps that generate an ongoing notification seem to be exempt, as is Google Maps, but if you start an app that will trigger the notification, you'll also see these "exempt" apps listed in the notification. So if you play music, you won't see the "running in the background" notification, but if you run another app, you'll see the new app and the music app listed in the "background" notification. The important thing is that you're always notified when an app is running in the background... and sometimes you're notified twice.

As always, there are a few exceptions to this "no background services" rule. If JobScheduler wakes up your app, either through a scheduled job or from an incoming "high-priority" message for things like chat apps, the app will be whitelisted for a bit and allowed to deal with the job. There are also exceptions for a few special, user-designated apps, like a keyboard app that is installed and activated, an active live wallpaper, any turned-on "Notification Listener" apps like the Android Wear companion app, and some accessibility apps like screen readers. OEMs are also allowed to do whatever they want in the background with their own apps.

(Somewhat) gracefully declining on older OSes

With the death of broadcasts and background services, some developers will have to do a bit of work if they want to target Oreo. Of course, with Android's eternal update problem, a very low percentage of devices will be on O for some time, so it's hard to encourage app developers to make the switch right now. One thing that will help is the new JobIntentService support library, which allows developers to write for the new Oreo way of doing background services while the library ensures compatibility with older versions of Android.

When using the JobIntentService library, developers get methods that will start a job on Android 8.0 and fall back to a service on an older version of Android. On Pre-O devices, the library will kick in and handle wakelocks for developers starting one when they need to do background work and killing the wakelock when the app is done. Given that JobScheduler was introduced in Android 5.0, I'm not really sure why this library seems to ignore the JobScheduler progress made from Android 5.0 to 7.1, but that's what the documentation says.

Limiting scans for location and Wi-Fi

Before Android 8.0, apps had unlimited background location usage. Google frequently cited background apps "polling once every second" in previous versions, which will chew through battery like crazy. Sometimes this was accidental, where apps would request precise location and in the foreground and forget to stop in the background. Other times, this was a developer being far too aggressive with background location requests.

In Android 8.0, Google is putting limits on background requests. For most cases while in the background, apps will be granted location updates about every 30 minutes. Apps are still free to request as often as they'd like, but the system will just continue providing old data and will only fire up the GPS and update the location at most every half hour.

Just like with the JobScheduler/Implicit broadcast change, this is mostly a case of limiting old, power-hungry, free-for-all APIs in an effort to push developers to switch to a newer, organized, more manageable API. There are many ways to request location in Android, and some methods (the older stuff) are being limited more than others.

Location Manager—The fact that this was introduced in Android 1.0 should tell you all you need to know about it. It gives manual access to the GPS, Wi-Fi, and cell location and it is almost always wrong to use this API. Now, it's limited to "a few times each hour."

Fused Location Provider—A second try at location introduced in the Android 4.2 era, but it was built into Google Play Services instead of directly into Android. Combines location information from the cellular signal, Wi-Fi, and GPS, and bundles it into a simple API for more battery-efficient location detection. Now limited to "a few times each hour."

Geofencing—A centralized location service in Google Play Services that lets developers declare a "geofence"—basically draw a shape on a map—and be alerted if the user enters or exits this area. This API is preferred for most background location usage, as the documentation states that "apps can receive geofencing transition events more frequently than updates from the Fused Location Provider" with an "average responsiveness for a geofencing event" of "every couple of minutes or so."

GNSSMeasurements/GnssNavigationMessage—This raw GPS data API was added in Nougat. Apps probably should not be using this unless they are a detailed GPS satellite data app. It's totally blocked in the background in Android 8.0.

Wi-Fi Manager—Not exactly a background location API, but apps could relentlessly pound on the background Wi-Fi scanning API to try and get a rough location. In Android 8.0, this is limited to once every 30 minutes per app.

Nothing is changed for foreground apps and services, so Google Maps Navigation will still work and your Uber driver will still be able to find you. Google's recommendation is that if an app really needs to perfectly know your location, it should start a foreground service, which will generate a notification to let the user know.

With all the background processing limits in Oreo, many people have wondered if they apply just to third-party apps or if Google will actually be limiting its own apps. For location updates, Google spells it out right in the documentation: "This behavior change affects all apps that receive location updates, including Google Play services."

A real API for floating apps

With Facebook Messenger open (or any other app that uses the System Alert API) Android triggers an "app is displaying over other apps" message.

In Android 7.1, a floating YouTube app is allowed to draw on top of the System UI (in this case, the notification panel). In Android 8.0, the notification panel correctly draws on top of all other apps.

The goal is to stop full-screen ransom-ware apps from taking over the entire phone. It's possible on Android 7.1, and harder on 8.0 thanks to the System UI being given priority again.

Android 1.0 introduced an API called "System Alert Window." This API was intended for, well, Android's system alert windows like crash notices and "Amber alerts." It was a public API that probably shouldn't have been public, though, and it started being used by apps like Facebook Messenger to draw floating windows on top of the entire device. Since it was never intended to be used by multiple apps at once (or by the public, at all), it has all sorts of problems. It doesn't have a sane way to manage Z order, there's no way to know what app is drawing a floating window, and there's no communication to the user about using system resources.

System Alert Window also breaks the normal Android layering conventions—it's possible to draw over top of the status bar, System UI, and lock screen. This has led to malicious apps picking up the API to do "clickjacking" or full-screen "ransomware" apps. The System Alert Window API allows such apps to lock you out of your device by covering up the system controls; these apps then demand payment to return control of your device.

Google began to rein in this API in Marshmallow by tagging it under a new "Draw over other apps" permission, but for apps that target Oreo, the API is dead. Google has a new API called "Application Overlays" that is purpose-built for Facebook Messenger-style overlay apps. The new API properly supports layering multiple apps, and it is in the correct Z space (above the foreground app but below the System UI). The API spawns an ongoing notification so users can see an app is using system resources, and it automatically identifies the app to the user.

Ron Amadeo
Ron is the Reviews Editor at Ars Technica, where he specializes in Android OS and Google products. He is always on the hunt for a new gadget and loves to rip things apart to see how they work. Emailron@arstechnica.com//Twitter@RonAmadeo