当我们创建一个Job时,我们可以设置很多属性,而setPeriodic(interval)对我来说有点令人困惑。文档说setPeriodic用于“指定此作业应以提供的间隔重复出现,每个周期不超过一次”。
我问这是因为我已经在一个工作上对其进行了测试:
JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(JOB_ID, mServiceComponent)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPeriodic(1000 * 60 * 15);
mJobScheduler.schedule(jobInfoBuilder.build());
该作业在30分钟内没有再次执行(此后我不再等待)。
答案 0 :(得分:1)
文档说setPeriodic用于“指定此作业应以提供的间隔重复出现,每个周期不超过一次”。
是的,它可以确保此作业在指定宽度的间隔内仅执行一次。实际的执行时间取决于操作系统,并受作业批处理等条件的影响,以便最大程度地减少手机从空闲状态唤醒所需的次数。
所以,我想,如果我将其设置为15分钟,它将不会每隔15分钟执行一次Job(前提是我没有为该作业指定任何其他条件)-这只是确保该作业的执行不超过一次在我为Job设置的时间间隔内,可能需要一个小时才能重新开始?
第一次调用该作业将在您的代码调用schedule
之后的15分钟内。之后,由于它是周期性的,它将在最后一个作业完成后的 15分钟之内再次执行,依此类推。通过在其他setPeriodic
方法中设置flexMillis
参数,我们无法控制在此间隔内何时执行作业。
比方说,您的工作的第一个执行是Job1。完成后,它将调度下一个作业实例-Job2。 Job2现在有2个边界-不能在Job1的时间间隔结束之前再次运行,并且必须在其自己的15分钟间隔结束之前运行。
JobService有一个方法jobFinished(),该方法需要一个布尔的needsReschedule,如果我将其设置为false,如果我将setPeriodic(1000 * 60 * 15)设置为false,Job将来还会重复吗?
docs中的wantsReschedule
参数说明如下:
布尔值:如果应根据首次计划时指定的退避条件重新计划此作业,则为true;否则为true。否则为假。
此处的“工作”是指您的定期工作的特定实例,而不是原始的定期工作。假设您要查询服务器以每小时显示一次通知,并且在执行作业时由于缺乏互联网而无法获取数据。您的作业可能已完成执行,但不满足更新数据的要求。如果将参数设置为true
,则此定期作业的实例将尝试根据退避策略(默认情况下为指数)重复自身。由于它被视为同一实例,因此它不违反“不会重复出现一次以上的时间”条件。
这意味着操作系统将反复尝试调度作业,直到完成参数false
为止。这样,您不必再等待一个小时来完成下一份工作,并且可以更快地尝试。 将根据初始定期设置执行下一个作业,而不管此参数是true
还是false
。
也就是说,这种重复的调度需要消耗大量电池,并可能导致许多冗余呼叫。在大多数情况下,可以通过将参数设置为false
来“删除”当前作业实例。下一个计划的作业仍将根据您的初始参数执行。
至于您的代码段,我不确定为什么不再次执行它。该代码似乎是正确的,只需确保您在整个时间段内都进行检查,而不是半小时后即可。还应考虑诸如Doze模式之类的特殊条件,它将阻止几乎所有后台服务的执行,并在以后自行重新安排它们的时间。