web-dev-qa-db-ja.com

WorkManagerがすでにスケジュールされているかどうかを確認します

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();
   }
_

解決策はありますか?

9
Khemraj

更新

重複した作品が欲しくないという理由だけで、既に実行中のワークマネージャーをチェックする必要がある場合。 enqueueUniquePeriodicWork() を使用するだけです

このメソッドを使用すると、一意の名前のPeriodicWorkRequestをキューに登録できます。特定の名前のPeriodicWorkRequestを一度に1つだけアクティブにできます。たとえば、1つの同期操作のみをアクティブにしたい場合があります。保留中のものがあれば、それを実行させるか、新しい作業に置き換えるかを選択できます。

したがって、作品の重複について心配する必要はありません。

_ workmanager.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP , photoCheckWork);
_
  • TAGは、作業マネージャーが重複をチェックする一意の名前です。
  • 選択 _ExistingPeriodicWorkPolicy.KEEP_と_ExistingPeriodicWorkPolicy.REPLACE_が可能です。

オリジナルポスト

見つからなかったときにこのメソッドを作成しました。

TAGで作業が実行されているかどうかを確認します

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);
}
_
43
Khemraj

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;
}
2
Irfan

2018年10月11日以降、削除されたSynchronousWorkManagerの代わりにListenableFutureを使用できます:

ListenableFuturesを使用して、同期して取得および監視できるようになりました。たとえば、WorkManager.enqueue()はvoidを返していました。これでListenableFutureが返されます。操作が完了したら、ListenableFuture.addListener(Runnable、Executor)またはListenableFuture.get()を呼び出してコードを実行できます。

詳細は こちら をご覧ください。

別のオプションを使用することができますListenableWorker

WorkManagerで非同期的に作業を実行できるクラス。ほとんどの場合、ワーカーを使用することをお勧めします。ワーカーは、事前に指定されたバックグラウンドスレッドで実行される単純な同期APIを提供します。

StartWork()関数を呼び出した後、ListenableFutureを返します。

詳細は こちら をご覧ください。

2
David Sucharda

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
    }
}
1
Abhishek