web-dev-qa-db-ja.com

WorkManager.getInstance()。cancelAllWorkByTag()が定期的なジョブを停止しない

定期的なタスクのために私はワークマネージャーを次のように使用しています:

PeriodicWorkRequest.Builder wifiWorkBuilder =
                            new PeriodicWorkRequest.Builder(FileUpload.class, 15,
                                    TimeUnit.MINUTES)
                                    .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.METERED).build());
                    PeriodicWorkRequest wifiWork = wifiWorkBuilder.build();
                    WorkManager.getInstance().enqueueUniquePeriodicWork("wifiJob", ExistingPeriodicWorkPolicy.REPLACE, wifiWork);

ユーザーがチェックボックスをオフにしてからこのジョブを停止したい場合、そのアクティビティにチェックボックスが1つあるアクティビティが1つあります。だから私は次のような仕事を止めています:

WorkManager.getInstance().cancelAllWorkByTag("wifiJob");

しかし、ジョブを停止した後、私のタスクも実行されています。以前は次のジョブが実行される可能性があると思っていましたが、その後停止しますが、最後の1時間で4回実行され、ジョブはバックグラウンドで実行されています。ジョブを停止する他の方法または正しい方法は何ですか。

ドキュメントごと:

指定されたタグを持つすべての未完了の作業をキャンセルします。キャンセルはベストエフォート型のポリシーであり、すでに実行中の作業は引き続き実行される可能性があることに注意してください。

これの意味は何ですか?キャンセルはベストエフォート型のポリシーであり、すでに実行中の作業は引き続き実行される可能性があります。これを止める正しい方法は何ですか

バージョンimplementation "Android.Arch.work:work-runtime:1.0.0-alpha08"を使用しています

6
PPD

PeriodicWorkRequestの作成中にaddTag()を追加し、同じタグ名を使用するタスクをキャンセルするには、これを使用して保留中の作業をキャンセルします。だから私のコードは次のようなものです:

PeriodicWorkRequest.Builder wifiWorkBuilder =
                            new PeriodicWorkRequest.Builder(FileUpload.class, 15,
                                    TimeUnit.MINUTES)
                                    .addTag("WIFIJOB1")
                                    .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.METERED).build());
                    wifiWork = wifiWorkBuilder.build();
                    WorkManager.getInstance().enqueueUniquePeriodicWork("wifiJob", ExistingPeriodicWorkPolicy.REPLACE, wifiWork);

私が使用しているジョブを停止するには:

WorkManager.getInstance().cancelAllWorkByTag("WIFIJOB1");
11
PPD

ここであなたが抱えている問題は、この 重複した質問 で答えられていると思います。

要約すると、まだ開始されていない保留中のワーカーがある場合、そのワーカーはキャンセルされ、実行されません。ただし、ワーカーがすでに実行されている場合、作業をキャンセルしてもワーカーは強制終了されません。ワーカーの状態フラグがCANCELLEDに設定されるだけです。 ドキュメントで説明されているようにdoWork内でキャンセルを処理し、ワーカーを終了するのはあなた次第です。

これを行う1つの方法は、isStopped()を呼び出して、doWorkメソッドにいくつかのチェックを入れ、ワーカーがキャンセルされたかどうかを確認することです。 isStoppedがtrueの場合、残りの作業を続行する代わりに、Resultを使用してメソッドから戻ります。

1
James Allen

私は公式をチェックしていますAndroid docs: https://developer.Android.com/reference/androidx/work/WorkManager

WorkManagerでサポートされる作業には、OneTimeWorkRequestPeriodicWorkRequestの2つのタイプがあります。

次のようにWorkManagerを使用してリクエストをエンキューできます。

 WorkManager workManager = WorkManager.getInstance();
 workManager.enqueue(new OneTimeWorkRequest.Builder(FooWorker.class).build());

WorkRequestには、次のように検索と監視に使用できるIDが関連付けられています。

WorkRequest request = new OneTimeWorkRequest.Builder(FooWorker.class).build();
 workManager.enqueue(request);
 LiveData<WorkStatus> status = workManager.getStatusById(request.getId());
 status.observe(...);

IDをキャンセルに使用することもできます。

WorkRequest request = new OneTimeWorkRequest.Builder(FooWorker.class).build();
 workManager.enqueue(request);
 workManager.cancelWorkById(request.getId());

そしてここでは、エンキューされた作業をキャンセルするさまざまな方法を確認できます。

enter image description here

ジョブの状態を使用して、エンキューまたはブロックされたジョブをキャンセルすることもできます。

WorkStatus workStatus = WorkManager.getInstance().getStatusById(wifiWork.getId()).getValue();
        if(workStatus.getState() == State.ENQUEUED || workStatus.getState() == State.BLOCKED){
            WorkManager.getInstance().cancelWorkById(wifiWork.getId());

        }

お役に立てば幸いです。

0