Scheduling Jobs With JobScheduler In Android

The JobScheduler API batches the similar work requests together and executes them based on available resources, specified condition, or interval. It improves the battery life and memory of the device because it has the ability to schedule background tasks with the tasks of other applications.

In daily coding life, we face a number of conditions where we need to perform some operations that need to be done after a certain time and/or with certain conditions like when the internet is available on the device. Android has many options (at application and system level) to do this but each option has its own characteristics. It could be useful to implement the proposed feature of your application but it could be very costly in terms of battery life and memory consumption. In order to overcome these issues, Android introduced JobScheduler in API level 21 (Android 5.0 | Lollipop).

JobScheduler

The JobScheduler API batches the similar work requests together and executes them based on available resources, specified condition or interval. It improves the battery life and memory of the device because it has the ability to schedule background tasks with the tasks of other applications.

In addition to the JobScheduler, there are several ways to schedule the jobs, as mentioned below. I will cover them in another article.

  • Alarm Manager
  • Firebase Job Dispatcher
  • SyncAdapter

In order to understand the JobScheduler, we need to know about its building blocks, like JobService and JobInfo.

JobService

JobService handles the asynchronous requests that were previously scheduled. This executes a task on a Handler running on our application’s main thread. That means if you want to perform a lengthy operation, do it in AsyncTask or Thread.

We have to override two methods - onStartJob(JobParameters) and onStopJob(JobParameters). The OnStartJob method indicates that a job has begun executing and we need to write the logic/code of the job. The OnStopJob method indicates that the system has determined that we must stop the execution of the job even before we have had a chance to call the jobFinished (JobParameters, boolean) method to stop a service.

Like other services or components, we have to register this in the manifest file. We have to specify the permission that will allow JobScheduler to call this job.

JobInfo

JobInfo is a container of data that is passed to the JobScheduler. It encapsulates the parameters required to schedule the work against the calling application.

I have created a demo application to show you how can we create a JobService and how can we schedule that with JobScheduler.

Create a JobService

I have created a JobService named MyJobService. Inside that, I am creating an object of LongRunningTask class. I just created it as an example. You can write your operation directly inside the onStartJob method.

  1. public class MyJobService extends JobService {  
  2.     private LongRunningTask mRunningTask;  
  3.     @Override  
  4.     public boolean onStartJob(JobParameters params) {  
  5.         if (mRunningTask == null)  
  6.             mRunningTask = new LongRunningTask();  
  7.         mRunningTask.startTask();  
  8.         return true;  
  9.     }  
  10.     @Override  
  11.     public boolean onStopJob(JobParameters params) {  
  12.         mRunningTask.finishTask();  
  13.         return true;  
  14.     }  
  15. }  
  16.   
  17. class LongRunningTask {  
  18.     private final String TAG = "LongRunningTask";  
  19.     private Timer mTimer;  
  20.     private int count = 0;  
  21.     LongRunningTask() {  
  22.     }  
  23.     void startTask() {  
  24.         if (mTimer == null)  
  25.             mTimer = new Timer();  
  26.           
  27.         mTimer.scheduleAtFixedRate(new TimerTask() {  
  28.             @Override  
  29.             public void run() {  
  30.                 Log.e(TAG, "Executing long running task " + count++);  
  31.             }  
  32.         }, 0, 1000);  
  33.     }  
  34.     void finishTask() {  
  35.         if (mTimer == nullreturn;  
  36.         mTimer.cancel();  
  37.     }  
  38. }  

Registering JobService in Manifest file

  1. <service  
  2.     android:name=".job_scheduler_example.MyJobService"  
  3.     android:enabled="true"  
  4.     android:exported="false"  
  5.     android:permission="android.permission.BIND_JOB_SERVICE" />  

Activity that is scheduling the job

  1. public class AnotherActivity extends AppCompatActivity {  
  2. private final String TAG = "AnotherActivity";  
  3. public static Intent getStartIntent(Context context) {  
  4.     Intent intent = new Intent(context, AnotherActivity.class);  
  5.     return intent;  
  6. }  
  7. @Override  
  8. protected void onCreate(Bundle savedInstanceState) {  
  9.     super.onCreate(savedInstanceState);  
  10.     setContentView(R.layout.activity_another);  
  11.   
  12. // Job Scheduler  
  13. final JobScheduler scheduler = (JobScheduler) getApplicationContext().getSystemService(JOB_SCHEDULER_SERVICE);  
  14. ComponentName componentName = new ComponentName(this, MyJobService.class);  
  15. JobInfo jobInfo = new JobInfo.Builder(JOB_ID, componentName)  
  16.         .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)  
  17.         .setPersisted(true)  
  18.         .build();  
  19. if (scheduler != null) {  
  20.     // Checking if job is already running  
  21.     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  22.         if (scheduler.getPendingJob(JOB_ID) == jobInfo)  
  23.             return;  
  24.     }  
  25.     scheduler.schedule(jobInfo);  
  26. }  
  27. }  

This is a very basic demo of scheduling a job with JobScheduler. If you face any issue implementing this, please let me know via the comments section.