Sunday 3 September 2017

Background Execution Limits on Android Oreo

There could be a bunch of reasons why our application is utilising background services — maybe it’s keeping our application data up-to-date with what’s on the server, maybe it’s shifting tasks to the background to unblock the UI or maybe we’re just carrying out some other long running task in the background. Whatever it is we’re doing, we’re going to be affected by these new changes in Android Oreo. But why has this change been introduced?
Well to begin with, Background Services are battery drainers — some applications can constantly be running services in the background (maybe to check your location for example), and this constant running of the service uses up a lot of battery on the device which isn’t really what you want for your users. But the main reason that this change was introduced was because background services can also have effects on application performance — so if numerous applications are running processes in the background, then the application in the foreground may suffer in terms of performance due to the processes being carried out in the background.
I think these are two good enough reasons alone to make a change in this direction, ensuring that our users can gain a smoother experience in our applications whilst also ensuring their device isn’t effecting at the same time.

So to put these changes into a nutshell, our applications no longer have the ability to freely run in the background — this means that if our application is either launched from an implicit broadcast, or if our application is launching services in the background, then these implementations will break with the introduction of Android Oreo.
Whilst this holds true for all applications that are targeting Android — users on older versions of Android can still choose to opt-in to apply these restrictions within application settings, so even if we’re not targeting O yet then we still need to be proactive about these changes.

Service Restrictions

So the first concept affected by these changes are Services. To begin with the most important thing to note is that if you attempt to call startService() when your application is not in the foreground then an IllegalStateException will be thrown. This means you can no longer use the startService() method when your app is not visible / being interacted with by the user. These change effects all services except those that:
  • Have been started when the application is currently in the foreground
  • Foreground Services
  • Bound Services
If your application is still going to be calling startService() from the foreground, then when your application moves to the background there is a small amount of time that that your service is given before it is shutdown. Whilst this shows that this approach can still be used, it’s probably not something you should rely on — for example for services using the network, if the user is experiencing a slow connection and your task is taking longer to complete, if your app moves to the background then the service could be destroyed before your task has been completed (and the user possibly being unaware that the task didn’t complete). Because of this, be mindful of the tasks you are carrying out in these cases and don’t rely on the task being completed within this grace period.

When the service does reach the point where it is to be shut down by the system in this situation, then the service is stopped as if the stopSelf()method has been called.

To avoid running into any issues with these changes now in place, there are a number of different approaches that we can take, these include:

-  Job Scheduler
- FCM + Service Whitlist
- Start Service In Forground
- Defer Task To The Foreground

Scheduling jobs

So to begin with, using a Job Scheduler allows us to move away from our background service implementation and let them system take care of the execution for us. The system will also be intelligent with the jobs that we schedule, so scheduling multiple jobs means that they can be grouped and executed at the same time. We can also schedule jobs to run based on certain criteria, such as network connectivity and device power status — so not only does adapting to these changes avoid issues with the way things are now, but it also allows our applications tasks to be run more efficiently.
You can check out the documentation for the Android Job Scheduler here. There is also the Firebase Job Dispatcher which allows you to achieve similar results when targeting lower than Android 5.0.

Firebase Cloud Messaging and Service Whitelist

When it comes to services running in the background, there is a whitelist which is used to allow applications to temporarily run in the background as if they were running in the foreground. Applications will be included on this whitelist in situations when they are:
  • - Being triggered from a high priority FCM/GCM notification
  • - Performing SMS/MMS delivery
  • - Acted from a Notification Action
So fore example, in cases where we may need our application data to be refreshed based off of changes on the server, we can use FCM to send our application a notification that can trigger a service to fetch the latest set of data. For this, using High Priority messages allows our application to be added to a service whitelist that allows our services to run as if they were in the foreground. High Priority messages from FCM will be received immediately, even when the system is in the Doze state —and this is that point that the application will also be added to the temporary service whitelist. This means that we can start our service to update our applications data as if our application was running in the foreground.

It’s important to note that this will only be the case for High Prioritymessages, other priority messages will be received when the device screen is turned back on or during the Doze maintenance window.

Starting a service in the foreground

In some cases, we may be running a service which is carrying out a task that the user may need to interact with or monitor the task that is being executed. Some examples of this could be when the user is downloading some new content in your app, using a timer to perform some time-base operation, or maybe they’re receiving navigational directions from your application — these are all situations where the user needs to be aware of the task at hand.
For these kind of situations, we can run our service in the foreground — this is because when running, foreground services use a persistent notification to make the user aware that they are currently running.
Previously, we were able to start foreground services by simply calling startForeground() directly — using this method directly no longer works, so we need to make use of the new startForegroundService() method. The method itself is the same as calling startService(), but with the contract that startForeground() will be called. The difference with using this method as compared to startService() is that we can call it at anytime, even if our application is not currently in the foreground.
We can implement this by:
  • First using the startForegroundService() method, passing an intent for our service task to be carried out. This method will create our background service that we must immediately promote to the foreground.
  • Within this service we need to create a notification to be displayed for our foreground service. This must be of at least Low priority or higher so that is shown to the user on screen — if the priority is set to PRIORITY_MIN then the notification will not be displayed to the user.
  • Next, we can call startForeground(id, notification) from within the service — this will promote our service to the foreground.
  • Defer task to the foreground

    If none of the above are appropriate solutions for your application, then another approach that can be taken is to simply defer the task to the foreground of the application. Personally I’d advice exploring the above solutions first as they will help you to avoid blocking your user interface and create a smoother experience for your user.
  • Broadcast Restrictions

    The second set of changes that comes with Android Oreo are related to Broadcast Receivers. So essentially, any broadcast receivers that we have defined statically within our application manifest that are listing for implicit broadcasts will not longer receive those broadcasts.
  • The reason for this change is that implicit broadcasts would previously trigger any component that was listening for them within the manifest— this could have an effect on application and device performance due to large numbers of applications registered to receive specific broadcasts all being triggered at the same time.
  • To avoid running into any issues with these changes now in place, there are a number of different approaches we can think about, these include:

  • - Broadcast Whitelist

    - Scheduling Jobs

    - Dynamic Broadcast 
    To begin with, there is a ‘short’ list of exceptions when it comes to implicit broadcasts — this means that are are still some which you can register to receive broadcasts for. This list includes all of the below:

     

  •  So if the broadcast that you have registered receivers for is on this list, then it will still function as it did previously (phew!). However, if the broadcast that you have registered to receive is not on this list then then an alternative solution that we can take is to register a Job to be executed when certain broadcast events take place.
    We touched on the JobScheduler slightly earlier, but with this API we have the ability to schedule jobs to be triggered intelligently when certain conditions are met, this could be in conditions such as:
    • The device connectivity status changes, such as becoming connected to a network or more specifically a WiFi network
    • When the device has entered a power charging state
    • When there has been content provider changes
    And finally, if our requirements are not satisfied by either of these solutions than we still have the ability to register are broadcast receivers programmatically within our classes.
  • In this situation, we can simply use the registerReceiver() method call to register a dynamic broadcast receiver within our activity — followed by unregisterReciever() to ensure we unregister subscriptions based on the lifecycle of our activity. The only difference here is that we’re registering these listeners programatically and clearing up their subscriptions when our activity no longer need them, rather than them being defined in our manifest to receive events as and when they please.
  • So as you can see from this, if your application is currently using any of the changes approaches above, then you will need to shift some implementations to ensure that things don’t break for your users.
    Whilst all of these changes are related to background tasks, things your user might not directly be aware of, it’s important to remember that these will have a positive effect whilst using applications by provided a smoother experience from a more efficient process flow for background tasks.
    Like always, do drop me a tweet or leave a comment below if you have any questions or suggestions for these changes to background tasks

Sunday 11 June 2017

Android 8.0 | Android O | Android Oreo

Announced at Google I/O 2017, Fluid Experiences is Google’s way of helping you be more productive and enjoy multi-tasking tools in your everyday use.


Android O Features & Functionality



Picture-in-Picture

A familiar phrase and tool in many televisions, within the YouTube app on Android and, yes, in iOS. Google is adding a Picture-in-Picture mode to Android O. With a YouTube video playing, just tap the Home button and the video will pop into a small window that can remain on screen as you navigate other apps on your device. You can slide the video around for best placement, then simply slide it off the screen to terminate. Available now in the Android O Beta.

Notification Dots

Many custom Launcher users already know the power of a notification icon on top of an app icon on your Homescreen. We even used Tasker to build our own once, but now Google is building it into Android. Android O users will see a small dot that appears over top of their app icons with active notifications. This is where the magic starts, now that your app has an icon, new tools are available – Long-press the app icon with Notification Dot to get a short list of immediate shortlink actions you can perform. This includes viewing the notification itself right there in a tiny pop-up window.
The long-press functionality is not yet available in Android O, watch for it coming soon in a future beta release.
Android O Notification Dots

Smart Text Selection

We’ve all seen the basic text highlighting features, the copy/paste dialogue in Android, but now there’s more. With Android O, highlighting text includes further features, using Google AI to intelligently act on the words. For instance, if you highlight a phone number, you can just tap to dial. If you highlight an address, a single tap will start navigation. Best of all, highlighting is more intelligent itself, selecting phrases or full addresses, for example, instead of just single words.
Android O Notification Dots

Auto-Fill

For your most used apps on your device, Android O will help quickly log into services. The Auto-Fill feature needs to be coded in by the app devs, but once installed, Android O will remember your usernames, and in some cases your password, to quickly and easily jump into apps on your device.

Vitals

Who wants better battery life? Android O will soon include features under the banner Vitals, including security tools, OS optimizations and tools for developers to better suite your device usage. At Google I/O 2017, the Android team announced Google Play Protect, think of it as a virus scanner for Android apps. So far, the team reports having scanned over 50 billion app installs every day. You’ll see an entry in your Google Play app update window, showing your most recent scan and if there were any issues found.Optimizations in the OS have the team reporting that Pixel devices are booting up in nearly half the time as before. This speed bump goes for apps as well. Extensive changes to the runtime, including things like concurrent, compacting garbage collection and code locality, but in Google’s words, your apps just run faster. More on this later.
Wise Limits will apply to background services, preventing apps from running in the background for too long. The goal is to dramatically reduce battery consumption, keeping you up and running through your day.
Android O Vitals

Notification handling

As for notification handling, there’s some familiar stuff going on as well as some new options. If you long press on a notification you’ll see a toggle for Notifications, allowing you to disable all future notifications from that app (when notification channels are fully introduced you’ll also have access to them here, but more on that below).
However, if you swipe a notification to the side a little, you’ll get two icons: one for accessing the Notifications toggle and a clock icon for snoozing the notification. If you tap the clock you’ll automatically snooze for 15 minutes but you can open the drop-down menu to snooze for 30 or 60 minutes instead or to disable snooze.

Quick Settings

When you open up the Quick Settings screen, you’ll see we still have different color schemes for the Pixels compared to Nexus devices. Nexuses get that same dark blue-gray background with aqua accents while the Pixels maintain the near-black and bright blue accent scheme.

Background Execution Limits on Android Oreo

There could be a bunch of reasons why our application is utilising background services — maybe it’s keeping our application data up-to...