Monday, 23 October 2017

Schedule Android Background Job Using Firebase JobDispatcher

From Android version 8.0 (Oreo) on wards there are limitations in executing background services and there are some limitations in receiving certain broadcasts. The android team implement all these restrictions to improve app performance and device battery life. If your app target API 26 then you have to consider some other mechanisms to do your background job. 
Fortunately there is JobScheduler API that solve the problem regarding the background job limitations in newer versions of android. Google suggests Android App developers to use the JobScheduler API for their background job execution rather than using a background service. 

But the problem is that the android framework JobScheduler API is available from android API version 21(Lollipop) and above. If your app support start from Lollipop and above then you can go for the framework JobScheduler API for your background job.


If your App support start from android API lower than 21 then you can use the Firebase JobDispatcher for performing your background operations. 



  • Firebase JobDispatcher API is available from Android API 9 and above. 
  • It uses the Android framework Job Scheduler API features for its operations. 
  • It needs google play service installed in the device.



So here we are going to create an Android example of how to use firebase JobDispatcher in your android application. 

 Step 1:
 Add the latest dependency for using firebase JobDispatcher in your android application. Open your android studio project module level gradle file and add the following dependency in the dependencies section. 
             
    "compile 'com.firebase:firebase-jobdispatcher:0.8.4'"

You can check here for the latest dependency. 

Step 2 :
Implement the job service class for defining your job. Create a new java class that extends JobService and implement the needed methods.

Here is the implementation of Firebase JobDispatcher JobService.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class MyService  extends JobService{

    BackgroundTask backgroundTask;

    @Override
    public boolean onStartJob(final JobParameters job) {

        backgroundTask = new BackgroundTask()
        {
            @Override
            protected void onPostExecute(String s) {
                Toast.makeText(getApplicationContext(),"Message from Background Task :"+s,Toast.LENGTH_LONG).show();
                jobFinished(job,false);
            }
        };

        backgroundTask.execute();
        return true;
    }



    @Override
    public boolean onStopJob(JobParameters job) {
        return true;
    }


    public static class BackgroundTask extends AsyncTask<Void,Void,String>
    {

        @Override
        protected String doInBackground(Void... voids) {
            return "Hello from background job";
        }
    }


}
  
In JobService class you need to implement two methods, onStartJob and onStopJob.

You have to place your job within the onStartJob method. The job service is executed on the main process thread, so if your job is a time taking one ( for example download a large file from server), then you have to run the job on a separate thread, otherwise the system may issue an Application Not Responding dialog.


In the above example i uses an AsyncTask for performing the background task. The AyncTask has a separate worker thread for the job.

Ads By Google

  • The return type of the onStartJob is a boolean. 
  • If you use a separate background thread for the job execution, then you have to return true from the onStartJob method. 
  • If you return true then you must call the method jobFinished() soon after the job finishes.  
  • jobFinished method needs two parameters, Job parameters and a boolean value. 
  • If you want to reschedule the same job again, then you can pass true as second parameter. 
  • If you forget to call the jobFinished() method, then the system assume that your job is still running in the background and that cause the JobService to run without any task and that leads faster battery drain.
  • If the task interrupted before finish, then the system call the onStopJob() method. You can clear all the unfinished job resources from here. If you want to reschedule the interrupted job again then you have to return true from this method.    

Step 3 :
Register the Job Service in Manifest file. Open your application AndroidManifest.xml file and add the following code in the application tag.


1
2
3
4
5
  <service android:name=".MyService">
            <intent-filter>
                <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"></action>
            </intent-filter>
        </service>

Job service is ready and now you can schedule the job.

Step 4 :
Start (Schedule) the job.
Here is the code segment that schedule the job.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
 public void startJob(View view)
    {
        String Job_Tag = "my_job_tag";
        FirebaseJobDispatcher jobDispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
        Job job = jobDispatcher.newJobBuilder().
                   setService(MyService.class).
                   setLifetime(Lifetime.FOREVER).
                   setRecurring(true).
                   setTag(Job_Tag).
                   setTrigger(Trigger.executionWindow(10,15)).
                   setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL).
                   setReplaceCurrent(false).
                   setConstraints(Constraint.ON_ANY_NETWORK)
                   .build();
        jobDispatcher.mustSchedule(job);
        Toast.makeText(this,"Job Scheduled..",Toast.LENGTH_SHORT).show();

    }
   

  • To schedule a job first you have to create an object of FirebaseJobDispatcher class.
  • You have to pass the GooglePlayDriver object to the constructor of FirebaseJobDispatcher.
  • You can create Job class object by calling the build method on JobBuilder.   
  • The job parameters are specified on the JobBuilder object. You can get the JobBuilder object by calling the newJobBuilder method using the FirebaseJobDispatcher object. 
  • setService() : Through this method you can specify the Job Service class in which you place your job. 
  • setLifeTime(): Specify the life span of the job. Default value is Lifetime.UNTIL_NEXT_BOOT
  • setRecurring() : Specify whether the job repeat or not. 
  • setTag() : Help the system to uniquely identify the job using its tag.
  • setTrigger() : Specify the job start time an repeating interval.
  • setRetryStratergy() :  Specify retry with exponential back off
  • setReplaceCurrent() : Specify whether or not replace the job having same tag. 
  • setConstraint() : Specify the job requirements. For example Constraint.ON_ANY_NETWORK (Run on any network), Constraint.DEVICE_CHARGING(Only run when device is charging) etc.   
  • Finally you can schedule the job by passing the job as a parameter to the mustSchedule method. 
  • You can call the mustSchedule method on the JobDispatcher object. 

Cancelling A Job : 
  • To cancel a particular job call the dispatcher.cancel('job Tag') method. 
  • To cancel all the jobs call dispatcher.cancelAll() method. 
Conclusion:
Firebase job dispatcher is the best choice for running background task in your android application from Android API version 9 and above. I hope you understand all the concepts.