JobScheduler定期工作

时间:2018-11-21 15:03:21

标签: android

当我们创建一个Job时,我们可以设置很多属性,而setPeriodic(interval)对我来说有点令人困惑。文档说setPeriodic用于“指定此作业应以提供的间隔重复出现,每个周期不超过一次”。

  • 所以,我想,如果我将其设置为15分钟,则不会每15分钟执行一次Job(前提是我没有为该作业指定任何其他条件)-这只是确保该作业的执行不超过一旦在我为Job设置的间隔内,可能要花一个小时才能重新开始?
  • JobService有一个方法jobFinished(),它需要一个布尔的needsReschedule,如果我将其设置为false,如果我将setPeriodic(1000 * 60 * 15)设置为Job,将来Job还会重复吗?

我问这是因为我已经在一个工作上对其进行了测试:

 JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(JOB_ID, mServiceComponent)
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
                    .setPeriodic(1000 * 60 * 15);

            mJobScheduler.schedule(jobInfoBuilder.build());

该作业在30分钟内没有再次执行(此后我不再等待)。

1 个答案:

答案 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模式之类的特殊条件,它将阻止几乎所有后台服务的执行,并在以后自行重新安排它们的时间。