24時間ごとに実行する必要があるWorker
インスタンスがありますが、これはPeriodicWorkRequest
APIを考えると非常に簡単です。しかし、ここに問題があります。
ユーザーが午後8時に作業を開始した場合、翌朝の午前9時に作業マネージャーの最初のインスタンスを実行してから、24時間の定期的な制約に従う必要があります。
私は here を見て、OneTimeWorkRequest APIに使用可能なsetInitialDelay()
関数があることを発見しましたが、PeriodicWork
APIについて何も見つかりませんでした。
これらはいくつかのハックです。たとえば、最初の遅延でOneTimeWork
を使用し、そこからPeriodicWork
をスケジュールすることができますが、それはちょっと汚いハックです。
PeriodicWorkRequest
APIだけでこれを行う方法はありますか?
WorkManager
(v1.0.0-alpha07
)、PeriodicWorkReqeust
の初期遅延を設定することは不可能だと思います。次のリリースでいくつかのAPIを取得する可能性があります。
当面は、先ほどお話ししたように、OneTimeWork
リクエストセットアップを初期遅延付きで使用できます。これにより、PeriodicWork
リクエストがWorkManagerにエンキューされます。
私はそれをハックと言いますが、それほど汚いものではありません。
PeriodicWorkRequestには、作業を実行できる間隔を渡すことができるNice Builderコンストラクタがあります。ビルダーと各パラメーターの詳細を確認できます ここ
したがって、定期的な作業に初期遅延を設定するには、次のようにします。
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に切り替えます。
それが役に立てば幸い!
新しいバージョンのワークマネージャ( バージョン2.1.0-alpha02 2019年5月16日にリリース)では、PeriodicWorkRequestsが初期遅延をサポートするようになりました。 PeriodicWorkRequest.BuilderでsetInitialDelayメソッドを使用して、初期遅延を設定できます。
例:
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
WorkerReminderPeriodic.class,
24,
TimeUnit.HOURS,
PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS,
TimeUnit.MILLISECONDS)
.setInitialDelay(1, TimeUnit.HOURS)
.addTag("send_reminder_periodic")
.build();
WorkManager.getInstance()
.enqueueUniquePeriodicWork("send_reminder_periodic", ExistingPeriodicWorkPolicy.REPLACE, workRequest);