【问题标题】:Scheduling Jobs with JobScheduler in Android在 Android 中使用 JobScheduler 调度作业
【发布时间】:2015-03-18 12:10:54
【问题描述】:

我对新 Android API 21 中的 JobScheduler 的作业计划有疑问。 这是我以 60 秒间隔安排作业的代码,如下所示:

ComponentName serviceName = new ComponentName(this, MyJobService.class);
JobInfo jobInfo = new JobInfo.Builder(0, serviceName)
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
        .setPeriodic(60000)
        .build();

My JobService 只打印 Logcat 中的运行时间,但日志显示服务在这个时刻运行:

03-18 08:37:26.334: I/JOB(32662): Wed Mar 18 08:37:26 BRT 2015
03-18 08:37:56.364: I/JOB(32662): Wed Mar 18 08:37:56 BRT 2015
03-18 08:39:21.418: I/JOB(32662): Wed Mar 18 08:39:21 BRT 2015
03-18 08:41:51.670: I/JOB(32662): Wed Mar 18 08:41:51 BRT 2015
03-18 08:45:52.192: I/JOB(32662): Wed Mar 18 08:45:52 BRT 2015
03-18 08:54:20.678: I/JOB(32662): Wed Mar 18 08:54:20 BRT 2015

这很奇怪,因为我使用 setPeriodic(60000) 方法设置的作业应该在 1 分钟内至少执行 1 次。 运行之间的间隔如何增加也很好奇。此时时间是 Wed Mar 18 09:09:00 BRT 2015,Job 不再执行。

JobScheduler API 有问题吗? (我在装有 Android 5.0.1 的 Nexus 5 中运行)

【问题讨论】:

    标签: android task scheduling jobs android-jobscheduler


    【解决方案1】:

    时间更改与重试作业的退避标准有关。默认情况下,它设置为指数。我猜你在完成工作时也没有正确完成工作,请致电jobFinished(JobParameters params, boolean needsReschedule)

    我写了一个blog post,它专注于与 JobScheduler 相关的所有小事。我强烈推荐阅读它。

    【讨论】:

    • Job Scheduler 工作正常,但如果我锁定屏幕,时间间隔会不断变化,任何适合我的解决方案
    • Job Scheduler 做得不好的一件事是确保您的作业运行的准确时间。我认为这将是按预期工作的情况。通过使用您的参数,您也许可以修复它。从技术上讲,现在您应该改用 WorkManager。几周前有一个关于它的 Google IO 演讲。 youtube.com/watch?v=IrKoBFLwTN0developer.android.com/reference/kotlin/androidx/work/…
    • 我试过了,问题是工作经理允许定期工作 15 分钟间隔,我必须每 60 秒运行一次工作,我可以通过任何其他方式在准确的时间范围内实现结果,我已经发布了问题能否请您说明如何在没有时间延迟的情况下做到这一点stackoverflow.com/questions/50753823/…
    【解决方案2】:

    我遇到了同样的问题,我认为这可能与 JobInfo 类的内部要求有关:

    Source code for JobInfo

        /* Minimum interval for a periodic job, in milliseconds. */
    private static final long MIN_PERIOD_MILLIS = 15 * 60 * 1000L;   // 15 minutes
    

    看来 JobInfo 不允许您将间隔设置为小于该值。

    【讨论】:

      【解决方案3】:

      //下面是我在我的一个项目中使用的代码,它对我来说工作正常。

      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
          public void scheduleJob(Context context) {
              //https://kb.sos-berlin.com/pages/viewpage.action?pageId=3638048
              //Scheduler uses UTC times for all its internal operations. This ensures a continual flow of operation without breaks or repetitions regardless of any changes in local time.
              JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(context, MyService.class));//JobSchedulerService.class.getName()));
              builder.setPersisted(true); //persist across device reboots
      
              builder.setPeriodic((120 * 60 * 1000)); //run once after 2 hours seconds
      
              builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // only if wifi avaiblable so they are not using bandwith
              builder.setRequiresDeviceIdle(false); // run not only if the device is idle
              builder.setRequiresCharging(false); // run not only if the device is charging
      
             // android.os.PersistableBundle bundle = new android.os.PersistableBundle();
              // bundle.putString(WEB_SERVICE_URL, "http://example.com?upload.php");
              //   builder.setExtras(bundle);
      
              //builder.setBackoffCriteria(1600, JobInfo.BACKOFF_POLICY_LINEAR);
              //BACKOFF_POLICY_LINEAR After one failure retry at 1 * your value, then at 2 * (your value), then 3 * (your value) and so on
              //BACKOFF_POLICY_EXPONENTIAL After one failure retry at your value, then at (your value)^2, (your value)^3 and so on
              //builder.setMinimumLatency(5 * 1000); //latency
              //builder.setOverrideDeadline(50 * 1000); //wait for criteria to be met, in 50 seconds if they have not then run anyways
      
      
              int test = jobScheduler.schedule(builder.build());
              if (test <= 0) {
                  Utility.showDialog(context, "Service Error", "Service is not responding");
                  //If something goes wrong
              }
          }
      

      我们根据以下说明定义了服务类:

      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
      public class MyService extends JobService {
      
          @Override
          @TargetApi(Build.VERSION_CODES.LOLLIPOP)
          public boolean onStartJob(final JobParameters params) {
      
              Log.e(TAG, "onStartJob");
      
              String month = "3";
              String year = "2018";           
      MyAsync myAsync = new MyAsync(MyService.this, arraydata, month, year, new SyncAsyncListener() {
                          @Override
                          public void onDataSuccess() {
                              try {
                                  jobFinished(params, result);
                              } catch (Exception e) {
      
                              }
                          }
                      });
      
                      myAsync.execute();
                  }
          return result;
      }
      @Override
      public boolean onStopJob(JobParameters jobParameters) {
          return false;
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-01
        • 2015-11-13
        • 1970-01-01
        • 2017-08-18
        • 2015-06-21
        • 2015-11-11
        • 2018-06-17
        • 1970-01-01
        相关资源
        最近更新 更多