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

drm*_*wer 19 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);
Run Code Online (Sandbox Code Playgroud)

因此,调度只有一个约束:网络连接(可以是"任何"或"未计量").

问题的简短版本

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

更长版本(带有ramblings)

问题

我发现,在某些设备上,如果在已经满足网络约束的时间段内安排作业,则作业将立即运行(或者足够快以便用户感知到).

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

现在,我很清楚这可能是JobScheduler...... 的意图是由系统来安排工作以最好地适应其他需求,并且无法保证在所有约束条件下作业将立即运行很满意.

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

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

setOverrideDeadline()不是解决方案?

我可以看到它JobInfo.Builder确实有一种setOverrideDeadline()方法,这几乎就是我想要的.但是,这指定了从安排作业开始的最大延迟(即,即使不满足所有约束,也在10秒内运行作业),而不是从满足所有约束的时间开始(即在所有约束条件下运行作业)约束得到满足).

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

那么Firebase JobDispatcher呢?

我看到Firebase JobDispatcher有一个Trigger.NOW触发器("意味着一旦满足运行时约束就应该运行Job").也许这就是如果JobScheduler不支持这种原生的方式?我被Firebase JobDispatcher推迟了,因为好像它正在使用大锤破解坚果......而Firebase似乎是关于云消息等的,这与本地任务调度(应该是完全是当地的关注).它似乎需要Google Play服务,这似乎对本地任务调度来说似乎完全没有必要.此外,如果使用Firebase立即触发它,而Firebase仅JobScheduler用于Android L +,那么必须直接执行此操作JobScheduler而不依赖于Firebase?

编辑:我现在尝试了这个,甚至Trigger.NOW不保证立即响应...实际上我发现我的设备上有几乎正好30秒的延迟,这很奇怪.

失败了......

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

或者可以手动检查初始约束,setOverrideDeadline()如果满足所有约束,则使用0 运行作业,否则运行它setOverrideDeadline().

只有拥有控制JobScheduler自身时间的能力似乎更为可取,有点像你可以使用的setWindow()方法AlarmManager.

小智 -1

作业调度程序用于调度作业:定期触发、延迟触发或限制其他作业。如果您想立即解雇一项工作,则不需要安排它,只需启动它即可。

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);
    }
Run Code Online (Sandbox Code Playgroud)