android N中的作业调度程序,间隔小于15分钟

tom*_*itz 18 android job-scheduling android-7.0-nougat

我的问题的一部分,我如何在"Nougat"中以不到15分钟的间隔建立一个工作,在他的答案中被"暴雪"回答:
Job Scheduler没有在Android N上运行
他解释了问题并建议使用以下解决方法:

JobInfo jobInfo;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
      .setMinimumLatency(REFRESH_INTERVAL)
      .setExtras(bundle).build();
} else {
  jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
      .setPeriodic(REFRESH_INTERVAL)
      .setExtras(bundle).build();
}    
Run Code Online (Sandbox Code Playgroud)

但是,使用建议

  .setMinimumLatency(REFRESH_INTERVAL)    
Run Code Online (Sandbox Code Playgroud)

刚开始工作一次;
但是如何在Android牛轧糖设备(不使用处理程序或报警管理器)上定期获得约30秒的周期?

MRa*_*Rah 10

如果有人仍在努力克服这种情况,

以下是> = Android N的解决方法(如果要将周期性作业设置为低于15分钟)

检查是否仅使用setMinimumLatency.此外,如果您正在运行需要很长时间的任务,则下一个作业将安排在,当前JOB结束时间+ PROVIDED_TIME_INTERVAL

.SetPeriodic(long millis)适用于Android N以下的API级别

@Override
public boolean onStartJob(final JobParameters jobParameters) {
    Log.d(TAG,"Running service now..");
    //Small or Long Running task with callback

    //Reschedule the Service before calling job finished
    if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
              scheduleRefresh();

    //Call Job Finished
    jobFinished(jobParameters, false );

    return true;
}

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

private void scheduleRefresh() {
  JobScheduler mJobScheduler = (JobScheduler)getApplicationContext()
                    .getSystemService(JOB_SCHEDULER_SERVICE);
  JobInfo.Builder mJobBuilder = 
  new JobInfo.Builder(YOUR_JOB_ID,
                    new ComponentName(getPackageName(), 
                    GetSessionService.class.getName()));

  /* For Android N and Upper Versions */
  if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      mJobBuilder
                .setMinimumLatency(60*1000) //YOUR_TIME_INTERVAL
                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
  }
Run Code Online (Sandbox Code Playgroud)

更新: 如果您正在考虑在打盹模式下运行重复作业并考虑JobScheduler,那么FYI:JobSchedulers不允许在打盹模式下运行.

我没有讨论过Dozing,因为我们谈论的是JobScheduler.谢谢,@ Elletlar,指出有些人可能会认为它会在应用程序处于打盹模式时运行,而事实并非如此.

对于打盹模式,AlarmManager仍然提供最佳解决方案.您可以使用setExactAndAllowWhileIdle() ,如果你想在精确的时间运行周期作业或使用setAndAllowWhileIdle()如果你是灵活的.

您还可以使用setAlarmClock()作为设备始终从打盹模式中输出闹钟并再次返回打盹模式.另一种方法是使用FCM.

参考:打盹限制

https://developer.android.com/training/monitoring-device-state/doze-standby


小智 0

当我想设置作业来刷新一小部分数据时,我遇到了同样的问题。我发现这个问题的解决方案可能是在我打电话后用相同的ID再次设置作业jobFinished(JobParameters, boolean)。我认为它每次都应该在主线程上工作。

我设置作业的函数如下所示:

JobInfo generateRefreshTokenJobInfo(long periodTime){
    JobInfo.Builder jobBuilder = new JobInfo.Builder(1L, new ComponentName(mContext, JobService.class));
    jobBuilder.setMinimumLatency(periodTime);
    jobBuilder.setOverrideDeadline((long)(periodTime * 1.05));
    jobBuilder.setRequiresDeviceIdle(false);
    return jobBuilder.build();
}
Run Code Online (Sandbox Code Playgroud)

当我在第一次调用 Job 后完成工作时,我在主线程中调用

jobFinished(mJobParameters, true);
registerRefreshJob(5*60*1000L);
Run Code Online (Sandbox Code Playgroud)

这将在相同的时间、相同的 ID 上再次重新安排我的作业。当设备处于空闲状态时,您仍然需要考虑打瞌睡时缺乏唤醒锁,因此您的工作可能不会像您希望的那样频繁启动。https://developer.android.com/about/versions/nougat/android-7.0-changes.html中提到

如果设备在进入 Doze 状态后静止一段时间,系统会将其余的 Doze 限制应用于 PowerManager.WakeLock、AlarmManager 警报、GPS 和 Wi-Fi 扫描。无论是否应用部分或全部 Doze 限制,系统都会唤醒设备进行短暂的维护窗口,在此期间应用程序可以访问网络并可以执行任何延迟的作业/同步。

  • 但请注意,作业调度程序会在一分钟内超时。如果您的任务花费超过一分钟,“jobFinished”将不会运行。超时后调用“onStopJob”。所以如果我是你,我也会在 `onStopJob` 中重新注册。 (3认同)