JobScheduler:控制从满足约束的延迟到正在运行的作业

时间:2016-09-07 07:33:16

标签: android alarmmanager android-jobscheduler

我使用JobScheduler来安排工作。主要是我将它用于.setRequiredNetworkType()方法,它允许您指定您只希望在建立网络连接(或更具体地说是未计量连接)时安排作业。

我使用以下相当简单的代码来安排我的工作:

PersistableBundle extras = new PersistableBundle();
extras.putInt("anExtraInt", someInt);
int networkConstraint = useUnmetered ? JobInfo.NETWORK_TYPE_UNMETERED : JobInfo.NETWORK_TYPE_ANY;

ComponentName componentName = new ComponentName(context, MyJobService.class);
JobInfo jobInfo = new JobInfo.Builder(jobId, componentName)
        .setRequiredNetworkType(networkConstraint)
        .setExtras(extras)
        .build();

JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(jobInfo);

因此,对时间安排只有一个限制:网络连接(可能是'任何'或'未计量')。

问题的简短版本

如何指定满足所有约束的最大延迟,以及实际运行作业,例如"在网络连接的2秒内运行作业"?

更长版本(带有ramblings)

问题

我发现在某些设备上,如果在网络约束已满足的时间段内安排作业,作业将立即运行(或者足够快到被用户认为是这样的。

但是在其他设备上,即使已经有合适的网络连接(这样作业可以立即运行),在实际运行之前会有很长的延迟。因此,如果这是对用户操作的回应,则会给人的印象是没有发生任何事情并且应用程序已损坏。

现在,我很清楚这可能是JobScheduler的意图......它可以让系统安排工作最适合其他需求,以及当所有约束都得到满足时,无法保证作业会立即运行。

但是,如果需要,能够对其进行某些控制会很好。因此,对于按计划进行的工作,在没有用户参与的情况下,让系统完全控制精确计时是好的和良好的。

但是,当作业响应用户操作时,我希望作业能够毫不拖延地运行...假设网络连接存在。 (如果没有连接,则可以显示一条消息,表明在恢复网络连接时将执行操作,然后JobScheduler负责确保在网络恢复时运行作业。)

setOverrideDeadline()不是解决方案吗?

我可以看到JobInfo.Builder确实有setOverrideDeadline()方法,这几乎就是我想要的。但是,这指定了从作业安排时起的最大延迟(即,即使所有约束都不满足,也会在10秒内运行作业并且时间不足),而不是从所有约束都具有的满意(即在满足所有约束条件的10秒内运行工作)。

编辑:并且似乎有一个恼人的错误,可能会导致作业在使用setOverrideDeadline()时运行两次:请参阅herehere

Firebase JobDispatcher怎么样?

我看到Firebase JobDispatcher有一个Trigger.NOW trigger("表示一旦满足运行时限制就应该运行Job")。如果JobScheduler本身不支持这种情况,那么这可能是最佳选择?我已经被Firebase JobDispatcher推迟了,因为看起来它似乎正在使用大锤来破解坚果......而且看起来Firebase完全是关于云消息等的,这与本地任务相去甚远调度(应该完全是本地关注的)。它似乎需要Google Play服务,这似乎对本地任务调度来说似乎完全没有必要。此外,如果使用Firebase立即触发它,Firebase只使用JobScheduler用于Android L +,那么必须直接使用JobScheduler直接执行此操作而不依赖Firebase吗?

编辑:我现在尝试了这个,甚至Trigger.NOW都不能保证立即回应......实际上我发现我的延迟几乎就是30秒设备,这是奇怪的。

失败......

目前,我能看到确保立即执行的唯一方法(如果满足约束条件)是使用JobScheduler

或者也许手动检查初始约束,如果满足所有约束,则运行setOverrideDeadline()为0的作业,否则运行它setOverrideDeadline()

仅仅能够控制JobScheduler本身的时间安排似乎更为可取,有点像使用AlarmManager的{​​{1}}方法。

1 个答案:

答案 0 :(得分:0)

作业调度程序用于调度作业:定期触发,延迟或限制其他作业。 如果你想立即开始工作,它不需要安排工作,只需启动它。

ConnectivityManager cm =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = cm.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {

        // If there is connectivity, Launch the job directly here

    } else {

        PersistableBundle extras = new PersistableBundle();
        extras.putInt("anExtraInt", someInt);
        int networkConstraint = useUnmetered ?       
        JobInfo.NETWORK_TYPE_UNMETERED : JobInfo.NETWORK_TYPE_ANY;

        ComponentName componentName = new ComponentName(context,MyJobService.class);
        JobInfo jobInfo = new JobInfo.Builder(jobId, componentName)
                .setRequiredNetworkType(networkConstraint)
                .setExtras(extras)
                .build();

        JobScheduler jobScheduler = (JobScheduler)      context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        jobScheduler.schedule(jobInfo);
    }