通过标记停止 WorkManager 并检查它是否是 运行 个问题

Stop WorkManager by tag and check if it is running problems

我已经阅读了几篇关于 WorkManager 如何在 Android 中工作的文章,但我仍然遇到问题。

这是我的实现:

implementation "androidx.work:work-runtime:2.2.0"

这是我的代码:

    public class NotificationWorker extends Worker {

        private static final String WORKER_TAG =    
             NotificationWorker.class.getSimpleName();

        public static void start(Context context){

            Constraints constraints = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build();

            PeriodicWorkRequest notificationWorker  =
                new PeriodicWorkRequest.Builder(
                    NotificationWorker.class,
                    30,
                    TimeUnit.MINUTES,
                    15,
                    TimeUnit.MINUTES
                ).setConstraints(constraints)
                .addTag(NotificationWorker.WORKER_TAG)
                .build();

            WorkManager.getInstance(context)
                .enqueueUniquePeriodicWork(
                    NotificationWorker.WORKER_TAG,
                    ExistingPeriodicWorkPolicy.KEEP,
                    notificationWorker
                );
        }

        public static void stop(Context context) {

            // THIS NOT STOP WORKER !
            WorkManager.getInstance(context)
                .cancelAllWorkByTag(NotificationWorker.WORKER_TAG);

           // THIS WORKS BUT STOP ALL WORKERS
           // WorkManager.getInstance(context).cancelAllWork();

         }

         public static boolean isScheduled(Context context) {

             // NOT WORKS!
             WorkManager instance = WorkManager.getInstance(context);
             ListenableFuture<List<WorkInfo>> statuses = instance
                 .getWorkInfosByTag(NotificationWorker.WORKER_TAG);
            try {
                boolean running = false;
                List<WorkInfo> workInfoList;
                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 | InterruptedException e) {
                e.printStackTrace();
                return false;
            } 
        }

        public NotificationWorker(
             @NonNull Context context,
             @NonNull WorkerParameters workerParams
        ) {
            super(context, workerParams);
        }

        @NonNull
        @Override
        public Result doWork() {
            // ...
        }
    }

WorkerManager 启动并正常工作。

第一个问题是 我无法使用 cancelAllWorkByTag 停止它 但只使用 cancelAllWork。在我的场景中,我只使用一个 Workmanager 所以这不是什么大问题,但是我想了解错误

第二个问题是如何知道WorkeManager是不是运行? 'isScheduled' 函数总是 returns false。 我已经读到,随着不同的实现,有些东西发生了变化,但我不知道如何更新代码。

感谢您的提示。

我不知道这是否只是一个拼写错误,但是您的 "running" 变量在 isScheduled(Context context) 方法上设置错误,在这里。

for (WorkInfo workInfo : workInfoList) {
     WorkInfo.State state = workInfo.getState();
     running = (state == WorkInfo.State.RUNNING || 
                    state == WorkInfo.State.ENQUEUED);
}

您正在使用 一个 | 而不是 两个 这意味着您需要使用 || 而不是 | 在做检查的时候。您发送的代码中的变量可能分配错误。

尝试回答您的第一个问题:您可以尝试使用以下代码停止工作程序:

manager.cancelUniqueWork(NotificationWorker.WORKER_TAG);

这背后的原因是您在将工作人员排入队列时使用 ID 而不是标签发送工作人员。 "NotificationWorker.WORKER_TAG" 不是标签,而是您使用此 ID 时的 ID:

WorkManager.getInstance(context)
            .enqueueUniquePeriodicWork(
                NotificationWorker.WORKER_TAG,
                ExistingPeriodicWorkPolicy.KEEP,
                notificationWorker
            );

编辑:我刚刚意识到您还调用了错误的方法来获取您添加的工人。可能不会添加标签,但肯定会添加 ID。因此,不要使用 manager.getWorkInfosByTag(NotificationWorker.WORKER_TAG),而是使用 manager.getWorkInfosForUniqueWork(NotificationWorker.WORKER_TAG) 来查看您是否可以 实际获取计划的工作。

您正在排队一件独特的作品,因此您必须使用相应的 cancelUniqueWork 方法 (https://developer.android.com/reference/androidx/work/WorkManager#cancelUniqueWork(java.lang.String))。您恰好将 name 参数称为 "tag",但就 WorkManager 而言,它不是 tag