JobScheduler and JobService are android interfaces added in API 21 to perform background tasks under certain conditions. ####JobScheduler JobScheduler is an API used to schedule multiple types of tasks based on application processes.

  • Object acquisition method:[Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)]
  • useJobInfo.Builder.JobInfo.Builder(int, android.content.ComponentName)Construct the JobInfo object and pass it as a parameter to the Schedule (JobInfo) method of JobSechduler.
  • If the conditions specified in JobInfo are met, the system starts the job execution in JobService.

The system holds WakeLock for your application while the task is executed, so the application doesn’t have to do extra work to make sure the device is woken up. ####JobService Public Abstract Class JobService extends Service JobService extends Service A special Service that processes asynchronous requests planned by the JobScheduler

  • To use JobService, you must first declare the service and permissions in androidmanifest.xml<service android:name="MyJobService" android:permission="android.permission.BIND_JOB_SERVICE"/ >
  • The application needs to implement the onStartJob(JobParameters) interface to execute the task logic.
  • The Service executes the planned task in a Handler running on the main thread, so the application needs to execute the business logic in another Thread/Handler /AsyncTask. Failure to do so may cause the main thread to block.
  • OnStopJob (android app. Job. JobParameters) interface is when planning the implementation of the “no longer meet the condition being executed (e.g., network interruption).

### Set up periodic tasks

    private static final int JOB_INFO_ID = 10001;
    private static final long JOB_PERIODIC = 5 * 1000L;
    private void onJobStartClick() {
        JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        ComponentName componentName = new ComponentName(this, MyJobService.class);
        JobInfo jobinfo = new JobInfo.Builder(JOB_INFO_ID, componentName)
                .setPeriodic(JOB_PERIODIC)
                .build();
    }
Copy the code

If the periodic is set to 5 seconds -> Run, JobService is not started. Why? # # # # # the minimum execution interval setPeriodic source to find the answer: android/frameworks/base/core/Java/android/app/job/JobInfo Java

/* Minimum interval for a periodic job, in milliseconds. */ private static final long MIN_PERIOD_MILLIS = 15 * 60 * 1000L; // 15 minutes /* Minimum flex for a periodic job, in milliseconds. */ private static final long MIN_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes /** * Specify that this job should recur with the provided interval, not more than once per * period. You have no control over when within this interval this job will be executed, * only the guarantee that it will be executed at most once within this interval. * Setting this function on the builder with {@link #setMinimumLatency(long)} or * {@link #setOverrideDeadline(long)} will result in an error. * @param intervalMillis Millisecond interval for which this job will repeat. */ public Builder setPeriodic(long intervalMillis) {  return setPeriodic(intervalMillis, intervalMillis); } /** * Specify that this job should recur with the provided interval and flex. The job can * execute at any time in a window of flex length at the end of the period. * @param intervalMillis Millisecond interval for which this job will repeat. A minimum * value of {@link #getMinPeriodMillis()} is enforced. * @param flexMillis Millisecond flex for this job. Flex is clamped to be at least * {@link #getMinFlexMillis()} or 5 percent of the period, whichever is * higher. */ public Builder setPeriodic(long intervalMillis, long flexMillis) { mIsPeriodic = true; mIntervalMillis = intervalMillis; mFlexMillis = flexMillis; mHasEarlyConstraint = mHasLateConstraint = true; return this; } /** * Query the minimum interval allowed for periodic scheduled jobs. Attempting * to declare a smaller period that this when scheduling a job will result in a * job that is still periodic, but will run with this effective period. * * @return The minimum available interval for scheduling periodic jobs, in milliseconds. */ public static final long getMinPeriodMillis() { return MIN_PERIOD_MILLIS; } /** * Set to the interval between occurrences of this job. This value is <b>not</b> set if the * job does not recur periodically. */ public long getIntervalMillis() { final long minInterval = getMinPeriodMillis(); return intervalMillis >= minInterval ? intervalMillis : minInterval; }Copy the code

To sum up a few points:

  • You can see that the system sets a minimum interval of 15 minutes by default. When obtaining the execution interval, the system compares the minimum interval with the set interval and takes the larger one. So setPeriodic does not take effect if the time is less than 15 minutes.
  • The flexMillis parameter is used to set the active time at which periodic tasks are executed, meaning that tasks scheduled by JobScheduler are not executed at precise times. The minimum time is 5 minutes by default.
  • SetMinimumLatency and setOverrideDeadline are not used together with setPeriodic, which causes errors.
/** * @return The job object to hand to the JobScheduler. This object is immutable. */ public JobInfo build() { // Allow  jobs with no constraints - What am I, a database? if (! mHasEarlyConstraint && ! mHasLateConstraint && mConstraintFlags == 0 && mNetworkType == NETWORK_TYPE_NONE && mTriggerContentUris == null) { throw  new IllegalArgumentException("You're trying to build a job with no " + "constraints, this is not allowed."); } // Check that a deadline was not set on a periodic job. if (mIsPeriodic) { if (mMaxExecutionDelayMillis ! = 0L) { throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " + "periodic job."); } if (mMinLatencyMillis ! = 0L) { throw new IllegalArgumentException("Can't call setMinimumLatency() on a " + "periodic job"); } if (mTriggerContentUris ! = null) { throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " + "periodic job"); } } if (mIsPersisted) { if (mTriggerContentUris ! = null) { throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " + "persisted job"); } if (! mTransientExtras.isEmpty()) { throw new IllegalArgumentException("Can't call setTransientExtras() on a " + "persisted job"); } if (mClipData ! = null) { throw new IllegalArgumentException("Can't call setClipData() on a " + "persisted job"); } } if (mBackoffPolicySet && (mConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) ! = 0) { throw new IllegalArgumentException("An idle mode job will not respect any" + " back-off policy, so calling setBackoffCriteria with" + " setRequiresDeviceIdle is an error."); } JobInfo job = new JobInfo(this); . return job; }Copy the code

#### How do I view the running of my JobService? Adb gives us the Dumpsys tool: ADB shell Dumpsys JobScheduler

JOB #u0a122/10001: 945a633 com.fantasy.android.demo/.android.job.MyJobService u0a122 tag=*job*/com.fantasy.android.demo/.android.job.MyJobService Source: uid=u0a122 user=0 pkg=com.fantasy.android.demo JobInfo: Service: com.fantasy.android.demo/.android.job.MyJobService PERIODIC: interval=+1h0m0s0ms flex=+1h0m0s0ms Requires: charging=false batteryNotLow=false deviceIdle=false Backoff: policy=1 initial=+30s0ms Has early constraint Has late constraint Required constraints: TIMING_DELAY DEADLINE Satisfied constraints: APP_NOT_IDLE DEVICE_NOT_DOZING Unsatisfied constraints: TIMING_DELAY DEADLINE Tracking: TIME Enqueue time: -5m38s906ms Run time: earliest=+54m21s65ms, latest=+1h54m21s65ms Last successful run: 2018-01-02 13:07:16 Ready: false (job=false user=true ! pending=true ! active=true ! backingup=true comp=true)Copy the code

#### Use of JobService: Inherit JobService to implement its two interfaces

public class MyJobService extends JobService{ private static final String TAG = "MyJobService"; @Override public boolean onStartJob(JobParameters jobParameters) { Log.d(TAG, "onStartJob-->"); return false; } @Override public boolean onStopJob(JobParameters jobParameters) { Log.d(TAG, "onStopJob-->"); return false; }}Copy the code
  • When Android is ready to execute the task, the service starts and receives the onStartJob() method call on the main thread.

This method returns false to indicate that the job is complete, and the system unties the JobService and calls JobService onDestroy() just as if it had called jobFinished() itself. If true is returned, the task is successfully started but not completed. In this case, the application can invoke jobFinished after the task is complete.

  • The onStopJob(JobParameters) method is called when the task is interrupted, for example, the user needs the service to run while charging. If the charger is unplugged before calling JobFinished(), onStopJob(…) The method is called, that is, everything stops immediately.

Call onStopJob (…). The method is to indicate that the service is about to be stopped, returning true to say: “The task should be scheduled to continue next time.” Returning false means, “Anyway, that’s the end of the matter and don’t plan for the next time.”

  • About jobFinished ()

Public final void jobFinished (JobParameters params, Boolean wantsReschedule) Used to inform JobScheduler that a task has been completed. Note: This method does not call onStopJob(), but onDestroy(). When wantsReschedule is set to true, the task needs to be executed at an additional time. The execution time is limited by JobInfo’s fallback rule.

#### setBackoffCriteria public [jobinfo. Builder] setBackoffCriteria (long initialBackoffMillis, int backoffPolicy)

  • InitialBackoffMillis is the wait interval for the first retry attempt, in milliseconds. The default parameters are:

DEFAULT_INITIAL_BACKOFF_MILLIS 30000 MAX_BACKOFF_DELAY_MILLIS 18000000

  • BackoffPolicy is the corresponding retreat policy. The preset parameters are as follows:

BACKOFF_POLICY_EXPONENTIAL binary exit, Retry_time (current_time, num_failures) = current_time + initial_backoff_millis * 2 ^ (num_failures – 1), Num_failures >= 1 BACKOFF_POLICY_LINEAR, Retry_time (current_time, num_failures) = current_time + initial_backoff_millis * num_failures, num_failures >= 1

# # # # how to view JobScheduler for application held WakeLock adb shell dumpsys power com. Fantasy. Android. The demo | grep Wake

Refer to the article: blog.csdn.net/allisonchen… Blog.csdn.net/allisonchen… www.cnblogs.com/chase1/p/72…