21 September 2018
With the introduction of Android 8 (Oreo), we get to know some new and interesting features and behavior changes of the Android new OS. One of them is “Background execution limits” and in this post, we look specifically at this new restriction that has been introduced for background services. Due to this behavior change now apps that are running in the background now having limitations on how to access background services and the broadcasts that are defined in Manifest. So if you’re using background services in your app then this change could affect your app. So now let’s have a look on what the actual change is, how it will affect the development and how we can handle it.
Reason behind the Limitation
This behavior change is introduced to improve the battery life and the usage of RAM when apps are in the background, which can result in better user experiences. Moreover, this change is introduced because background services are also unfavorable for application performance. When more than one apps are performing any task in the background then it will affect the performance of the application which is running in the foreground. Also if some additional apps or services are running in background puts extra load on the device system which again affects UI.
How it Effects on Android App development?
There could be so many reasons we are using background services or broadcast like to keep your data updated as per the server changes or UI changes on the particular event or may be for performing some long-running task. For whatever reason we are using background task it will be affected by development. Overcoming this limitation will be majorly helpful for client application development for any Android app development company.
What are the Changes?
- The ‘startService()’ method now throws an ‘IllegelStateException’. If we try to use this method in the case of background services it will not allow.
- For starting foreground service we have now ‘Context.startForegroundService()’ method. This method can be called even when the app is in the background but the app must call that service’s method ‘startForeground()’ within five seconds after the service is created.
How to Handle Limitation?
There are three ways to overcome from this limitation, namely –
- Job Scheduler
- Foreground Service
Now let’s discuss each in detail below:
- Job Scheduler
Job Scheduler is introduced in API 21 for performing background tasks. This allows us to move away from background service implementation and just to focus on execution. Using this we can run scheduled services and Android system will set all the services from different apps in one group or set and execute them together in particular time. The reason behind this is to reduce the amount of time phone’s CPU and radio wakes up by batching the tasks together. This will consume less battery. The only drawback of Job Scheduler is it can only be run API 21 or above.
- Once the device is connected to a power supply, task should be done.
- Tasks that require network availability or a Wi-Fi reachability.
- The task that is not user-facing or critical.
- Where the timing is not critical the Tasks should be running on a regular basis as the batch
To implement a Job, extend the JobService class and implement the onStartJob and onStopJob. If the job scheduler fails for some reason, return true from on the onStopJob to restart the job. The method onStartJob is performed in the main thread, if you start asynchronous processing in this method, return True otherwise False.
The new JobService must be registered in the Android manifest with the BIND_JOB_SERVICE permission.
And now, below is the snippet to schedule the job.
ComponentName serviceComponent = new ComponentName(context,TestJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(0,serviceComponent);
builder.setMinimumLatency(1 * 1000);
builder.setOverrideDeadline(3 * 1000);
JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
Here to overcome the drawback of JobSchedular we can use FCM, FCM is supported from API Level 19.
When services are running in the background there are some scenarios which allow applications to temporarily run in the background as if they were running in the foreground. Applications will be included on these scenarios in situations when they are:
- To trigger high priority FCM/GCM notification
- To perform SMS/MMS delivery
- Capture Notification Action
We can send FCM notification to trigger a service of our application. For this, using High Priority messages allows our application to be added to a service in those scenarios which allows our services to run as if they were in the foreground because High Priority message will be received even when the system is in Doze Mode so by doing this we can start our service to update our application’s data if our application was not running in the background or killed. In FCM we must remember set message to High Priority otherwise messages will be received when the device screen is turned back on or during the Doze maintenance window.
- Foreground Services:
Another simple way is to make service foreground. Sometimes running service carrying out the task which may require user interaction or monitoring the task which is being executed. Like user downloading some data, using a timer to perform some time-based operation or receiving navigational directions from your application, these are the cases where we can use foreground service. When running foreground services use a persistent notification to acknowledge the user aware that they are currently running.
Before Android Oreo, if you wish to create a foreground service, you mostly start a background service by calling startService(). Then we can start our foreground service by assigning an ongoing notification using startForeground() method. But from Android Orio startService() will not be working nowadays, so for starting foreground service we must use startForegroundService() method, this method is static and belongs to the class NotificationManager. This method is the same as to creating background service and promoting it to the foreground service combine. The method itself is the as calling startService(), but with the contract that startForeground () will be called. The main difference with using this method as compared to startService () is that we can call it at any time, even if our application is not currently in the foreground.
Using the startForegroundService() method, passing an intent for our service task to be carried out. This tricks will create our background service that we must immediately promote to the foreground. Within use of this service, we need to create a notification to be displayed for our foreground service. This must be of at least higher priority or Low 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. And then, android app developers can call startForeground(id, notification) from within the service — this will promote our service to the foreground.
These limitations applied to the background service might lead to some difficulties in development but these will definitely provide extended battery life and also lower RAM usage. So ultimately it will make your applications smooth and your user happy.