Android – Creating scheduled background tasks
This tutorial is the first in the Background processing in Android tutorials series I will be posting for the following weeks. We will start with background services and follow up with thread pools, and foreground services . We are starting with a quick demo, then the available methods for creating scheduled background services in Android then we’ll see how to build one using Jobschedulers and JobServices.
What we’ll build
We’ll simply keep on displaying a toast after killing the app.
Implementing background tasks in Android
In the previous post we explained that Android services are application components that perform certain operations without providing a user interface and that foreground services are noticeable by the user as they display an undismissable notification, while background services are not noticeable by the user. One way to create background services in Android is using the IntentService class. Others ways to do so are using AsyncTasks , or using Jobschedulers, which are a custom implementation of the AlarmManger class, or using the GCM Network Manager .
I reference this great post on Choosing the right background scheduler in Android in case you need to get a clear explanation of each and a when-to-use-each guide.
In our case, according to the official documentation, if we’re implementing a background service to be run when the app itself isn’t in the foreground and targeting API level 26 or higher, then system imposes restrictions on running background services , and we have to use a scheduled job instead. Which is the case in our demo app where the service kept running when the app isn’t in the foreground.
Scheduled background tasks with JobSchedulers
To work with JobSchedulers you have to consider three things :
- What is the task to be executed in the background ?
The task you are wanting to schedule should be defined in a JobService : a class extending JobService in which you implement the methods onStartJob() and onStopJob(). This jobService will run on the main thread. Which means that you need to manage any asynchronous tasks yourself (using a Thread or AsyncTask within your onStartJob() method). In our example case, the JobService we would implement is the following :
MyBackgroundService.java :
public class MyBackgroundService extends JobService { private JobParameters params; private myTask doThisTask; @Override public boolean onStartJob(JobParameters params) { this.params = params; doThisTask = new myTask(); doThisTask.execute(); return false; } @Override public boolean onStopJob(JobParameters params) { if (doThisTask != null) doThisTask.cancel(true); return false; } private class myTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { /** displaying a toast ... **/ Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "DONE !", Toast.LENGTH_SHORT).show(); } }); return null; } @Override protected void onPostExecute(Void aVoid) { jobFinished(params, false); super.onPostExecute(aVoid); } } }
- Under which condition this task would run
As explained in the previous section, the greatest advantage of JobSchedulers is that they dont perform work based on time only, but rather based on conditions. Which means you no longer need a repeating alarm to go off every few hours so that you can check to see if now is a good time to sync with your server.
You can define these conditions through the JobInfo object. To build a JobInfo object you need your JobService and a job number to help you distinguish which job this is. So, in our MainActivity, we’ll be creating a JobInfo as follows:
JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName((MainActivity.this), MyBackgroundService.class))
Then, we’ll add the conditions we want to include in our JobInfo object. In the case of our demo, we only set our service to be scheduled for running each two seconds using setPeriodic(2000) .
In the general case, you have the ability to define various conditions for your JobInfo . Using for example,
setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) or setRequiresBatteryNotLow(boolean batteryNotLow) .
Those conditions can be on charging and Idle, minimum latency and override deadline, or network type. You can also pass extras in your JobInfo, and can define some backoff condtions .
- When to schedule the task
After defining the task and how would it run, we simply need to schedule it using using JobScheduler . Which is as simple as the following :
JobScheduler jobScheduler = (JobScheduler) (MainActivity.this).getSystemService(JOB_SCHEDULER_SERVICE); jobScheduler.schedule(jobInfo);
One final step is to add your service to app’s manifest as follows:
<service android:name=".MyBackgroundService" android:permission="android.permission.BIND_JOB_SERVICE" />
You can check out the full source code for the demo app for this tutorial. And read about background processing in Android in my previous post. For the next tutorial, we’ll follow up with Foreground services in Android.
Recent Comments