Android implements background services using JobService

Preface
Android often implements timing services, pushing messages or updating data at a certain time. Generally, we may open the service, use Alarm Manager and setRepeating timing requests in Service, but since API 19, it can not guarantee the accuracy of the timeliness. After 5.0, Google launched a JobService to execute some background processes that are not immediately executed.

Use
There are two abstract methods in JobService: onStartJob(JobParameters) and onStopJob(JobParameters). OnStartJob will execute when JobService is scheduled. We just need to inherit JobService and rewrite the onStartJob method and execute our background tasks in it.

   @Override
    public boolean onStartJob(JobParameters params) {
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }

In API, there is such a sentence

This service executes each incoming job on a Handler running on your application's
main thread. This means that you must offload your execution logic to another
thread/handler/AsyncTask of your choosing. Not doing so will result in blocking any
future callbacks from the JobManager - specifically onStopJob(android.app.job.JobParameters), which is meant to inform you that the
scheduling requirements are no longer being met.
Namely: JobService handles every incoming operation by default in the main thread, which means that you have to open a new line.
Programs perform your time-consuming operations, and if they do not, they will block any operations from JobManager, especially onStopJob operations.

In the onStartJob method, our timing service will be executed mainly by Job Scheduler.
Let's start with a simple example. Start a JobService, and loop through it to play a toast.

stay Activity In, start the service
 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            doService();
        }
  }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void doService() {
        JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(this, TestService.class));  //Specify which JobService performs the operation
        builder.setMinimumLatency(TimeUnit.MILLISECONDS.toMillis(10)); //Minimum latency of execution
        builder.setOverrideDeadline(TimeUnit.MILLISECONDS.toMillis(15));  //Maximum latency of execution
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NOT_ROAMING);  //Non-roaming network state
        builder.setBackoffCriteria(TimeUnit.MINUTES.toMillis(10), JobInfo.BACKOFF_POLICY_LINEAR);  //Linear Retry Scheme
        builder.setRequiresCharging(false); // Uncharged state
        jobScheduler.schedule(builder.build());
    }
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class TestService extends JobService {

    @Override
    public boolean onStartJob(JobParameters params) {
        doJob();
        doService();
        return true;
    }

    private void doService() {
        JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(this, TestService.class));  //Specify which JobService performs the operation
        builder.setMinimumLatency(TimeUnit.MILLISECONDS.toMillis(10)); //Minimum latency of execution
        builder.setOverrideDeadline(TimeUnit.MILLISECONDS.toMillis(15));  //Maximum latency of execution
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NOT_ROAMING);  //Non-roaming network state
        builder.setBackoffCriteria(TimeUnit.MINUTES.toMillis(10), JobInfo.BACKOFF_POLICY_LINEAR);  //Linear Retry Scheme
        builder.setRequiresCharging(false); // Uncharged state
        jobScheduler.schedule(builder.build());
    }

    private void doJob() {
        ToastUtil.ToastNormal(this, "test");
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }
}
        <!--register-->
        <service
            android:name=".service.TestService"  
            android:permission="android.permission.BIND_JOB_SERVICE"/>

As you can see in the example, there are five conditions.
- Minimum Latency
- Maximum delay time set Override Deadline
- Network state setRequired Network Type at execution time (NETWORK_TYPE_NONE default), (NETWORK_TYPE_ANY any network state), (NETWORK_TYPE_UNMETERED does not need to measure network state), (NETWORK_TYPE_NOT_ROAMING non-roaming state)
- The first parameter of retrial scheme setBackoff Criteria is time. The second one is JobInfo.BACKOFF_POLICY_LINEAR restriction scheme and BACKOFF_POLICY_EXPONENTIAL index scheme.
- Need to execute setRequiresCharging in the charging state by default false
In addition, there are
- Repeat weekly intervals set Periodic
- Whether to continue backstage operation setPersisted after device reboot, provided that it has permission
- setTriggerContentMaxDelay sets the maximum total delay (in milliseconds) allowed to detect content changes from the first * time until jobs are scheduled

summary
  • Inherit JobService and override onStartJob and onStopJob methods
  • When declaring JobService in manifest.xml, add android:permission="android.permission.BIND_JOB_SERVICE"
  • JobService can't perform time-consuming tasks. If you have to do this, you must open new threads to operate.
  • JobService must set at least one execution condition, such as network connection, charging, system idle.

If our background task satisfies one or more constraints of JobService, we can consider whether it should be executed with JobService.

Keywords: Android network Google xml

Added by jrinco11 on Thu, 20 Jun 2019 04:16:04 +0300