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

时间:2016-09-22 14:03:33

标签: android job-scheduling android-7.0-nougat

我的一部分问题是,如何在" Nougat"中以不到15分钟的间隔建立一份工作,被#34;暴雪"在他的回答中:
Job Scheduler not running on 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();
}    

但是,使用建议的

  .setMinimumLatency(REFRESH_INTERVAL)    

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

2 个答案:

答案 0 :(得分:8)

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

以下是> = 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);
  }

<强>更新 如果您在打盹模式中考虑重复工作并考虑JobScheduler, FYI:JobSchedulers不允许在打盹模式下运行。

我没有讨论过Dozing,因为我们谈论的是JobScheduler。谢谢, @Elletlar ,指出有些人可能认为即使应用处于打盹模式也会运行,但实际情况并非如此。

对于打盹模式,AlarmManager仍然提供最佳解决方案。如果要在确切时间段运行定期作业或使用,可以使用 setExactAndAllowWhileIdle() > setAndAllowWhileIdle()如果你很灵活的话。

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

参考:打盹限制

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

答案 1 :(得分:0)

当我想设置Job来刷新一小部分数据时,我在同样的事情上挣扎。我发现这个问题的解决方案可能是在我调用jobFinished(JobParameters, boolean)之后再次使用相同的ID设置Job。我认为它应该每次都在主线程上工作。

我设置Job的功能如下:

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();
}

当我第一次打电话给我完成工作后,我打电话给主线程

jobFinished(mJobParameters, true);
registerRefreshJob(5*60*1000L);

这将在同一个id上相同的时间内重新安排我的工作。当设备处于空闲状态时,您仍然需要考虑在打瞌睡时缺少唤醒锁定,因此您的工作可能无法按照您的意愿频繁启动。它在https://developer.android.com/about/versions/nougat/android-7.0-changes.html

中提到
  

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