web-dev-qa-db-ja.com

WorkRequestがWorkManagerによって以前にエンキューされたかどうかを確認しますAndroid

PeriodicWorkRequestを使用して、15分ごとにタスクを実行しています。この定期的な作業依頼が以前に予定されているかどうかを確認したいと思います。そうでない場合は、スケジュールしてください。

     if (!PreviouslyScheduled) {
        PeriodicWorkRequest dataupdate = new PeriodicWorkRequest.Builder( DataUpdateWorker.class , 15 , TimeUnit.MINUTES).build();
        WorkManager.getInstance().enqueue(dataupdate);
      }

以前はJobSchedulerを使用してタスクを実行していたとき、以前は

public static boolean isJobServiceScheduled(Context context, int JOB_ID ) {
    JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE ) ;

    boolean hasBeenScheduled = false ;

    for ( JobInfo jobInfo : scheduler.getAllPendingJobs() ) {
        if ( jobInfo.getId() == JOB_ID ) {
            hasBeenScheduled = true ;
            break ;
        }
    }

    return hasBeenScheduled ;
}

スケジュールされた/アクティブな作業要求を見つけるために、作業要求用の同様のモジュールを構築するのに助けが必要です。

13
Bhavita Lalwani

PeriodicWorkRequestタスクにタグを設定します。

    PeriodicWorkRequest work =
            new PeriodicWorkRequest.Builder(DataUpdateWorker.class, 15, TimeUnit.MINUTES)
                    .addTag(TAG)
                    .build();

次に、enqueue()が機能する前に、TAGでタスクを確認します。

    WorkManager wm = WorkManager.getInstance();
    ListenableFuture<List<WorkStatus>> future = wm.getStatusesByTag(TAG);
    List<WorkStatus> list = future.get();
    // start only if no such tasks present
    if((list == null) || (list.size() == 0)){
        // shedule the task
        wm.enqueue(work);
    } else {
        // this periodic task has been previously scheduled
    }

ただし、それが以前にスケジュールされたかどうかを本当に知る必要がない場合は、次のように使用できます。

    static final String TASK_ID = "data_update"; // some unique string id for the task
    PeriodicWorkRequest work =
            new PeriodicWorkRequest.Builder(DataUpdateWorker.class,
                    15, TimeUnit.MINUTES)
                    .build();

    WorkManager.getInstance().enqueueUniquePeriodicWork(TASK_ID,
                ExistingPeriodicWorkPolicy.KEEP, work);

ExistingPeriodicWorkPolicy.KEEPは、タスクが1回だけスケジュールされ、デバイスの再起動後も定期的に機能することを意味します。タスクを再スケジュールする必要がある場合(たとえば、タスクの一部のパラメーターを変更する必要がある場合)は、ここでExistingPeriodicWorkPolicy.REPLACEを使用する必要があります。

18
Alex

すべてのWorkRequestに一意のタグを追加する必要があります。チェック タグ付き作業

タグ文字列を任意のWorkRequestオブジェクトに割り当てることにより、タスクを論理的にグループ化できます。そのためには WorkRequest.Builder.addTag() を呼び出す必要があります

以下を確認Androidドキュメントの例:

_OneTimeWorkRequest cacheCleanupTask =
    new OneTimeWorkRequest.Builder(MyCacheCleanupWorker.class)
.setConstraints(myConstraints)
.addTag("cleanup")
.build();
_

PeriodicWorkRequestに使用できるのと同じ

次に、 WorkManager.getStatusesByTag() を使用して、そのタグが付いたすべてのタスクのすべてのWorkStatusのリストを取得します。

LiveData タグ付きの作品の WorkStatus のリストが表示されます。

次に、以下のようにWorkStatusを使用してステータスを確認できます。

_       WorkStatus workStatus = listOfWorkStatuses.get(0);

        boolean finished = workStatus.getState().isFinished();
        if (!finished) {
            // Work InProgress
        } else {
            // Work Finished
        }
_

詳細については、以下のgoogleの例を確認してください。ここでは、WorkRequestにタグを追加し、タグによって作業のステータスを取得する方法を追加しました。

https://github.com/googlecodelabs/Android-workmanager

編集以下のコードを確認し、タグでWorkStatusを取得する方法についてコメントします。そして、WorkStatusの結果が空の場合は、Workをスケジュールします。

_ // Check work status by TAG
    WorkManager.getInstance().getStatusesByTag("[TAG_STRING]").observe(this, listOfWorkStatuses -> {

        // Note that we will get single WorkStatus if any tag (here [TAG_STRING]) related Work exists

        // If there are no matching work statuses
        // then we make sure that periodic work request has been previously not scheduled
        if (listOfWorkStatuses == null || listOfWorkStatuses.isEmpty()) {
           // we can schedule our WorkRequest here
            PeriodicWorkRequest dataupdate = new PeriodicWorkRequest.Builder( DataUpdateWorker.class , 15 , TimeUnit.MINUTES)
                    .addTag("[TAG_STRING]")
                    .build();
            WorkManager.getInstance().enqueue(dataupdate);
            return;
        }

        WorkStatus workStatus = listOfWorkStatuses.get(0);
        boolean finished = workStatus.getState().isFinished();
        if (!finished) {
            // Work InProgress
        } else {
            // Work Finished
        }
    });
_

私はコードをテストしていません。フィードバックをお寄せください。

これがお役に立てば幸いです。

1
pRaNaY

私も同じ条件を探していましたが、見つからなかったため、この問題を解決するためのメカニズムを見つけました。これにより、作業のインスタンスが1つだけ維持されるようになります。また、そのようなワーカーコードロジックを維持する必要があることを確認してください。

作業のキャンセルに。 more の場合

UUID compressionWorkId = compressionWork.getId();
WorkManager.getInstance().cancelWorkById(compressionWorkId);
0
AtHul Antony