【问题标题】:job scheduler in android N with less then 15 minutes intervalandroid N中的作业调度程序,间隔少于15分钟
【发布时间】:2016-09-22 14:03:32
【问题描述】:

我的部分问题是,如何在“牛轧糖”中设置间隔少于 15 分钟的工作,“暴雪”在他的回答中回答了这里:
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 nougat 设备(不使用处理程序或警报管理器)上以大约 30 秒的周期定期获取它?

【问题讨论】:

  • 每 30 秒做一次,除非你的应用程序在前台并被用户积极使用,这在用户眼中是不合适的,他们大声抱怨后台应用程序的电池消耗。
  • 但是,如果您的用户希望在启动手机时获得最新信息(也许他们现在没有互联网......),则需要可靠的后台服务。还是您想告诉我,这显然是不可能的?那么你就可以这样做,而不用试图教我我知道的事情。
  • “如果您的用户希望在启动手机时获得最新信息”——这不需要每 30 秒工作一次。 “或者你是想告诉我,这显然是不可能的?” -- 没有什么可以可靠地做到这一点,除非您的应用程序处于前台并且正在被积极使用。
  • 我还希望它每 20 或 30 秒触发一次,但仅在调试时触发。等待 15 分钟看看你的代码是否有效是个笑话。这肯定应该是 Android 开发者设置中的一个选项吗?
  • 等待 15 分钟调试是浪费时间。有调试设置吗?

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


【解决方案1】:

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

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

检查是否只使用了 setMinimumLatency。另外,如果您正在运行一个需要很长时间的任务,下一个作业将被安排在,当前作业完成时间 + 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);
  }

更新: 如果您正在考虑在 Doze Mode 下运行重复作业并考虑 JobScheduler,仅供参考:JobScheduler 不允许在 Doze 模式下运行。

我没有讨论打瞌睡,因为我们在谈论 JobScheduler。感谢 @Elletlar 指出,有些人可能认为即使应用程序处于打瞌睡模式,它也会运行,但事实并非如此。

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

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

参考:打瞌睡限制

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

【讨论】:

  • 没有讨论打瞌睡?我很难相信这个解决方案会在设备被拔出并且屏幕因 SDK_INT >= Build.VERSION_CODES.N 而关闭时继续工作。
  • @Elletlar,当我回答这个问题时,我没有考虑打盹模式,主要是因为我们正在讨论 JobScheduler 并且在打盹模式下,无论您将其设置为低于还是超过 15 分钟,JobScheduler 都会受到限制。如果我必须需要频繁运行重复服务(包括在打盹模式下),我会使用警报管理器。也可以使用 FCM。
  • 谢谢。我只是认为在答案中提到这一点会很好,因为许多开发人员只会在他们实现它之后才会注意到这种行为。我一直在为我的一个旧应用程序评估 JobScheduler,但我认为 AlarmManager 中的 setExactAndAllowWhileIdle 仍然为选择设置频繁同步间隔的用户提供了最佳结果。
  • 是的,setExactAndAllowWhileIdle() 如果您在时间上不灵活,而 setAndAllowWhileIdle() 如果您灵活,则在打盹模式下提供最佳结果。顺便说一句,我正在更新答案,因为不了解打盹模式的人可能不会关注此讨论。
  • @Elletlar,更新了答案以包括打盹模式。谢谢。
【解决方案2】:

当我想设置 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();
}

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

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

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

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

【讨论】:

  • 请注意,jobscheduler 会在 1 分钟后超时。如果您的任务需要超过一分钟,jobFinished 将不会运行。 onStopJob 在超时后被调用。所以如果我是你,我也会在onStopJob 内重新注册。
  • android 5.1.1 1 分钟的限制
猜你喜欢
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
相关资源
最近更新 更多