WorkManager
が既にスケジュールされているかどうかを確認するにはどうすればよいですか?
WorkManager
をスケジュールするコードは次のとおりです。
_public static void scheduleWork() {
PeriodicWorkRequest.Builder photoCheckBuilder =
new PeriodicWorkRequest.Builder(WorkManagerService.class, TIME_INTERVAL_IN_SECONDS,
TimeUnit.SECONDS);
PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();
WorkManager instance = WorkManager.getInstance();
if (instance != null) {
instance.enqueueUniquePeriodicWork("TAG", ExistingPeriodicWorkPolicy.KEEP , photoCheckWork);
}
}
_
Application
クラスのscheduleWork()
でonCreate()
を呼び出します。 この方法でサービスが実行されているかどうかを確認することさえできます。ただし、WorkManagerが既にスケジュールされている場合、スケジュールされた時間の不整合を除去するようにスケジュールしたくありません。
いいね
_if(!workManagerIsScheduled())
{
scheduleWork();
}
_
解決策はありますか?
重複した作品が欲しくないという理由だけで、既に実行中のワークマネージャーをチェックする必要がある場合。 enqueueUniquePeriodicWork() を使用するだけです
このメソッドを使用すると、一意の名前のPeriodicWorkRequestをキューに登録できます。特定の名前のPeriodicWorkRequestを一度に1つだけアクティブにできます。たとえば、1つの同期操作のみをアクティブにしたい場合があります。保留中のものがあれば、それを実行させるか、新しい作業に置き換えるかを選択できます。
したがって、作品の重複について心配する必要はありません。
_ workmanager.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP , photoCheckWork);
_
ExistingPeriodicWorkPolicy.KEEP
_と_ExistingPeriodicWorkPolicy.REPLACE
_が可能です。見つからなかったときにこのメソッドを作成しました。
if (your_work_manager.version >= 1.0.0-alpha11)
_private boolean isWorkScheduled(String tag) {
WorkManager instance = WorkManager.getInstance();
ListenableFuture<List<WorkInfo>> statuses = instance.getWorkInfosByTag(tag);
try {
boolean running = false;
List<WorkInfo> workInfoList = statuses.get();
for (WorkInfo workInfo : workInfoList) {
WorkInfo.State state = workInfo.getState();
running = state == WorkInfo.State.RUNNING | state == WorkInfo.State.ENQUEUED;
}
return running;
} catch (ExecutionException e) {
e.printStackTrace();
return false;
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
_
if (your_work_manager.version < 1.0.0-alpha11)
_private boolean isWorkScheduled(String tag) {
WorkManager instance = WorkManager.getInstance();
LiveData<List<WorkStatus>> statuses = instance.getStatusesByTag(tag);
if (statuses.getValue() == null) return false;
boolean running = false;
for (WorkStatus workStatus : statuses.getValue()) {
running = workStatus.getState() == State.RUNNING | workStatus.getState() == State.ENQUEUED;
}
return running;
}
_
タスクの一部がtrue
またはRUNNING
の場合、ENQUEUED
を返します。
_public static final String TAG_MY_WORK = "mywork";
if(!isWorkScheduled(TAG_MY_WORK)) { // check if your work is not already scheduled
scheduleWork(TAG_MY_WORK); // schedule your work
}
public static void scheduleWork(String tag) {
PeriodicWorkRequest.Builder photoCheckBuilder =
new PeriodicWorkRequest.Builder(WorkManagerService.class, TIME_INTERVAL_IN_SECONDS,
TimeUnit.SECONDS);
PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();
WorkManager instance = WorkManager.getInstance();
instance.enqueueUniquePeriodicWork(tag, ExistingPeriodicWorkPolicy.KEEP , photoCheckWork);
}
_
from1.0.0-alpha11と多くのものWorkStatusは機能しませんそれは削除され、重大な変更です。 リリースノートを確認
WorkStatusはWorkInfoに名前が変更されました。対応するすべてのgetStatusメソッドバリアントは、対応するgetWorkInfoバリアントに名前が変更されました。これは重大な変更です。
alpha11に更新した後、作業コードは。
private boolean isWorkScheduled(List<WorkInfo> workInfos) {
boolean running = false;
if (workInfos == null || workInfos.size() == 0) return false;
for (WorkInfo workStatus : workInfos) {
running = workStatus.getState() == WorkInfo.State.RUNNING | workStatus.getState() == WorkInfo.State.ENQUEUED;
}
return running;
}
2018年10月11日以降、削除されたSynchronousWorkManagerの代わりにListenableFutureを使用できます:
ListenableFuturesを使用して、同期して取得および監視できるようになりました。たとえば、WorkManager.enqueue()はvoidを返していました。これでListenableFutureが返されます。操作が完了したら、ListenableFuture.addListener(Runnable、Executor)またはListenableFuture.get()を呼び出してコードを実行できます。
詳細は こちら をご覧ください。
別のオプションを使用することができますListenableWorker:
WorkManagerで非同期的に作業を実行できるクラス。ほとんどの場合、ワーカーを使用することをお勧めします。ワーカーは、事前に指定されたバックグラウンドスレッドで実行される単純な同期APIを提供します。
StartWork()関数を呼び出した後、ListenableFutureを返します。
詳細は こちら をご覧ください。
Kotlinを使用している場合、このような拡張関数を書くことができます
fun WorkManager.isAnyWorkScheduled(tag: String): Boolean {
return try {
getWorkInfosByTag(tag).get().firstOrNull { !it.state.isFinished } != null
} catch (e: Exception) {
when (e) {
is ExecutionException, is InterruptedException -> {
e.printStackTrace()
}
else -> throw e
}
false
}
}