/** * @return Whether this {@link Job} is periodic or not. If this {@link Job} is periodic, then * you shouldn't return {@link Result#RESCHEDULE} as result. * @see JobRequest#isPeriodic() */ public boolean isPeriodic() { return mRequest.isPeriodic(); }
/*package*/ long getBackoffOffset() { if (isPeriodic()) { return 0L; } long offset; switch (getBackoffPolicy()) { case LINEAR: offset = mFailureCount * getBackoffMs(); break; case EXPONENTIAL: if (mFailureCount == 0) { offset = 0L; } else { offset = (long) (getBackoffMs() * Math.pow(2, mFailureCount - 1)); } break; default: throw new IllegalStateException("not implemented"); } return Math.min(offset, TimeUnit.HOURS.toMillis(5)); // use max of 5 hours like JobScheduler }
.build(); if (newJob && (request.isExact() || request.isPeriodic() || request.isTransient())) { throw new IllegalArgumentException("Daily jobs cannot be exact, periodic or transient");
public static boolean startWithTransientBundle(@NonNull Context context, @NonNull JobRequest request) { // transientExtras are not necessary in this case Intent intent = PlatformAlarmServiceExact.createIntent(context, request.getJobId(), null); PendingIntent pendingIntent = PendingIntent.getService(context, request.getJobId(), intent, PendingIntent.FLAG_NO_CREATE); if (pendingIntent == null) { return false; } try { CAT.i("Delegating transient job %s to API 14", request); pendingIntent.send(); } catch (PendingIntent.CanceledException e) { CAT.e(e); return false; } if (!request.isPeriodic()) { cancel(context, request.getJobId(), pendingIntent); } return true; }
/** * Cancel this request if it has been scheduled. Note that if the job isn't periodic, then the * time passed since the job has been scheduled is subtracted from the time frame. For example * a job should run between 4 and 6 seconds from now. You cancel the scheduled job after 2 * seconds, then the job will run between 2 and 4 seconds after it's been scheduled again. * * @return A builder to modify the parameters. */ public Builder cancelAndEdit() { // create a temporary variable, because .cancel() will reset mScheduledAt long scheduledAt = mScheduledAt; JobManager.instance().cancel(getJobId()); Builder builder = new Builder(this.mBuilder); mStarted = false; if (!isPeriodic()) { long offset = JobConfig.getClock().currentTimeMillis() - scheduledAt; long minValue = 1L; // 1ms builder.setExecutionWindow(Math.max(minValue, getStartMs() - offset), Math.max(minValue, getEndMs() - offset)); } return builder; }
private void handleResult(Job job, Job.Result result) { JobRequest request = mJob.getParams().getRequest(); boolean incFailureCount = false; boolean updateLastRun = false; if (!request.isPeriodic() && Job.Result.RESCHEDULE.equals(result) && !job.isDeleted()) { request = request.reschedule(true, true); mJob.onReschedule(request.getJobId()); updateLastRun = true; } else if (request.isPeriodic()) { updateLastRun = true; if (!Job.Result.SUCCESS.equals(result)) { incFailureCount = true; } } if (!job.isDeleted()) { // otherwise it would be persisted again if (incFailureCount || updateLastRun) { //noinspection ConstantConditions request.updateStats(incFailureCount, updateLastRun); } } } }
long waited = System.currentTimeMillis() - request.getScheduledAt(); String timeWindow; if (request.isPeriodic()) { timeWindow = String.format(Locale.US, "interval %s, flex %s", JobUtil.timeToString(request.getIntervalMs()), JobUtil.timeToString(request.getFlexMs())); if (!request.isPeriodic()) { request.setStarted(true); mJobManager.getJobStorage().remove(request); } else if (!request.isPeriodic()) { mJobManager.getJobStorage().remove(request);
if (request.isExact()) { exact++; } else if (request.isPeriodic()) { periodic++; } else { if (!request.isPeriodic()) { continue;
@Test public void testFlex() { JobConfig.forceApi(JobApi.V_14); long interval = JobRequest.MIN_INTERVAL * 5; long flex = JobRequest.MIN_FLEX * 5; JobRequest request = getBuilder() .setPeriodic(interval, flex) .build(); JobManager.instance().schedule(request); assertThat(request.getJobId()).isGreaterThan(0); assertThat(request.getTag()).isEqualTo(DummyJobs.SuccessJob.TAG); assertThat(request.getIntervalMs()).isEqualTo(interval); assertThat(request.getFlexMs()).isEqualTo(flex); assertThat(request.isPeriodic()).isTrue(); assertThat(request.isFlexSupport()).isTrue(); }
@Test public void testPeriodic() { long interval = JobRequest.MIN_INTERVAL * 5; JobRequest request = getBuilder() .setPeriodic(interval) .setExtras(new PersistableBundleCompat()) .build(); assertThat(request.getJobId()).isGreaterThan(0); assertThat(request.getTag()).isEqualTo(DummyJobs.SuccessJob.TAG); assertThat(request.getIntervalMs()).isEqualTo(interval); assertThat(request.getFlexMs()).isEqualTo(interval); assertThat(request.isPeriodic()).isTrue(); assertThat(request.isFlexSupport()).isFalse(); assertThat(request.getStartMs()).isNegative(); assertThat(request.getEndMs()).isNegative(); assertThat(request.getBackoffMs()).isEqualTo(JobRequest.DEFAULT_BACKOFF_MS); assertThat(request.getBackoffPolicy()).isEqualTo(JobRequest.DEFAULT_BACKOFF_POLICY); assertThat(request.getExtras()).isNotNull(); assertThat(request.isExact()).isFalse(); assertThat(request.requiredNetworkType()).isEqualTo(JobRequest.DEFAULT_NETWORK_TYPE); assertThat(request.requirementsEnforced()).isFalse(); assertThat(request.requiresCharging()).isFalse(); assertThat(request.requiresDeviceIdle()).isFalse(); }
boolean periodic = request.isPeriodic(); boolean flexSupport = periodic && jobApi.isFlexSupport() && request.getFlexMs() < request.getIntervalMs();
/** * @return Whether this {@link Job} is periodic or not. If this {@link Job} is periodic, then * you shouldn't return {@link Result#RESCHEDULE} as result. * @see JobRequest#isPeriodic() */ public boolean isPeriodic() { return mRequest.isPeriodic(); }
/*package*/ long getBackoffOffset() { if (isPeriodic()) { return 0L; } long offset; switch (getBackoffPolicy()) { case LINEAR: offset = mFailureCount * getBackoffMs(); break; case EXPONENTIAL: if (mFailureCount == 0) { offset = 0L; } else { offset = (long) (getBackoffMs() * Math.pow(2, mFailureCount - 1)); } break; default: throw new IllegalStateException("not implemented"); } return Math.min(offset, TimeUnit.HOURS.toMillis(5)); // use max of 5 hours like JobScheduler }
.build(); if (newJob && (request.isExact() || request.isPeriodic() || request.isTransient())) { throw new IllegalArgumentException("Daily jobs cannot be exact, periodic or transient");
public static boolean startWithTransientBundle(@NonNull Context context, @NonNull JobRequest request) { // transientExtras are not necessary in this case Intent intent = PlatformAlarmServiceExact.createIntent(context, request.getJobId(), null); PendingIntent pendingIntent = PendingIntent.getService(context, request.getJobId(), intent, PendingIntent.FLAG_NO_CREATE); if (pendingIntent == null) { return false; } try { CAT.i("Delegating transient job %s to API 14", request); pendingIntent.send(); } catch (PendingIntent.CanceledException e) { CAT.e(e); return false; } if (!request.isPeriodic()) { cancel(context, request.getJobId(), pendingIntent); } return true; }
/** * Cancel this request if it has been scheduled. Note that if the job isn't periodic, then the * time passed since the job has been scheduled is subtracted from the time frame. For example * a job should run between 4 and 6 seconds from now. You cancel the scheduled job after 2 * seconds, then the job will run between 2 and 4 seconds after it's been scheduled again. * * @return A builder to modify the parameters. */ public Builder cancelAndEdit() { // create a temporary variable, because .cancel() will reset mScheduledAt long scheduledAt = mScheduledAt; JobManager.instance().cancel(getJobId()); Builder builder = new Builder(this.mBuilder); mStarted = false; if (!isPeriodic()) { long offset = JobConfig.getClock().currentTimeMillis() - scheduledAt; long minValue = 1L; // 1ms builder.setExecutionWindow(Math.max(minValue, getStartMs() - offset), Math.max(minValue, getEndMs() - offset)); } return builder; }
private void handleResult(Job job, Job.Result result) { JobRequest request = mJob.getParams().getRequest(); boolean incFailureCount = false; boolean updateLastRun = false; if (!request.isPeriodic() && Job.Result.RESCHEDULE.equals(result) && !job.isDeleted()) { request = request.reschedule(true, true); mJob.onReschedule(request.getJobId()); updateLastRun = true; } else if (request.isPeriodic()) { updateLastRun = true; if (!Job.Result.SUCCESS.equals(result)) { incFailureCount = true; } } if (!job.isDeleted()) { // otherwise it would be persisted again if (incFailureCount || updateLastRun) { //noinspection ConstantConditions request.updateStats(incFailureCount, updateLastRun); } } } }
long waited = System.currentTimeMillis() - request.getScheduledAt(); String timeWindow; if (request.isPeriodic()) { timeWindow = String.format(Locale.US, "interval %s, flex %s", JobUtil.timeToString(request.getIntervalMs()), JobUtil.timeToString(request.getFlexMs())); if (!request.isPeriodic()) { request.setStarted(true); mJobManager.getJobStorage().remove(request); } else if (!request.isPeriodic()) { mJobManager.getJobStorage().remove(request);
boolean periodic = request.isPeriodic(); boolean flexSupport = periodic && jobApi.isFlexSupport() && request.getFlexMs() < request.getIntervalMs();