我使用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秒内运行作业"?
问题
我发现在某些设备上,如果在网络约束已满足的时间段内安排作业,作业将立即运行(或者足够快到被用户认为是这样的。
但是在其他设备上,即使已经有合适的网络连接(这样作业可以立即运行),在实际运行之前会有很长的延迟。因此,如果这是对用户操作的回应,则会给人的印象是没有发生任何事情并且应用程序已损坏。
现在,我很清楚这可能是JobScheduler
的意图......它可以让系统安排工作最适合其他需求,以及当所有约束都得到满足时,无法保证作业会立即运行。
但是,如果需要,能够对其进行某些控制会很好。因此,对于按计划进行的工作,在没有用户参与的情况下,让系统完全控制精确计时是好的和良好的。
但是,当作业响应用户操作时,我希望作业能够毫不拖延地运行...假设网络连接存在。 (如果没有连接,则可以显示一条消息,表明在恢复网络连接时将执行操作,然后JobScheduler
负责确保在网络恢复时运行作业。)
setOverrideDeadline()不是解决方案吗?
我可以看到JobInfo.Builder
确实有setOverrideDeadline()
方法,这几乎就是我想要的。但是,这指定了从作业安排时起的最大延迟(即,即使所有约束都不满足,也会在10秒内运行作业并且时间不足),而不是从所有约束都具有的满意(即在满足所有约束条件的10秒内运行工作)。
编辑:并且似乎有一个恼人的错误,可能会导致作业在使用setOverrideDeadline()
时运行两次:请参阅here和here。
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}}方法。
答案 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);
}