PeriodicWorkRequest 有一个不错的 Builder 构造函数,您可以在其中传递工作可以执行的时间间隔。可以查看Builder的详细信息和各个参数here
因此,要为您的定期工作设置初始延迟,您可以这样做:
int hourOfTheDay = 10; // When to run the job
int repeatInterval = 1; // In days
long flexTime = calculateFlex(hourOfTheDay, repeatInterval);
Constraints myConstraints = new Constraints.Builder()
.setRequiresBatteryNotLow(true)
.build();
PeriodicWorkRequest workRequest =
new PeriodicWorkRequest.Builder(MyNiceWorker.class,
repeatInterval, TimeUnit.DAYS,
flexTime, TimeUnit.MILLISECONDS)
.setConstraints(myConstraints)
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork(YOUR_NICE_WORK_TAG,
ExistingPeriodicWorkPolicy.REPLACE,
workRequest);
这就是神奇发生的地方:
private long calculateFlex(int hourOfTheDay, int periodInDays) {
// Initialize the calendar with today and the preferred time to run the job.
Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.HOUR_OF_DAY, hourOfTheDay);
cal1.set(Calendar.MINUTE, 0);
cal1.set(Calendar.SECOND, 0);
// Initialize a calendar with now.
Calendar cal2 = Calendar.getInstance();
if (cal2.getTimeInMillis() < cal1.getTimeInMillis()) {
// Add the worker periodicity.
cal2.setTimeInMillis(cal2.getTimeInMillis() + TimeUnit.DAYS.toMillis(periodInDays));
}
long delta = (cal2.getTimeInMillis() - cal1.getTimeInMillis());
return ((delta > PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS) ? delta
: PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS);
}
请注意,这个时间并不准确。 WorkManager 可能会在该弹性窗口中随时触发您的作业,具体取决于您的约束、系统负载、其他计划作业等。
如果您想要精确计时,请切换到 AlarmManager。
希望对你有帮助!