17

我每 15 分钟使用 PeriodicWorkRequest 为我执行一项任务。我想检查一下,这个定期工作请求是否之前已经安排好了。如果没有,请安排它。

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

需要帮助为工作请求构建类似的模块,以帮助查找计划/活动的工作请求。

4

4 回答 4

31

为 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 意味着任务将只安排一次,然后即使在设备重新启动后也会定期工作。如果您需要重新安排任务(例如,如果您需要更改任务的某些参数),则需要在此处使用 ExistingPeriodicWorkPolicy.REPLACE

于 2018-10-30T07:49:27.917 回答
1

您需要为每个 WorkRequest 添加一个唯一的标签。检查标记的工作

您可以通过将标签字符串分配给任何 WorkRequest 对象来对您的任务进行逻辑分组。为此,您需要致电WorkRequest.Builder.addTag()

检查下面的 Android 文档示例:

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

同样你可以使用PeriodicWorkRequest

然后,您将使用该标签获得所有任务的所有 WorkStatus 列表WorkManager.getStatusesByTag()

它为您提供了带有标签的工作LiveData列表。WorkStatus

然后您可以使用 WorkStatus 检查状态,如下所示:

       WorkStatus workStatus = listOfWorkStatuses.get(0);

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

您可以查看下面的谷歌示例以获取更多详细信息。在这里,他们添加了如何向 WorkRequest 添加标签并通过标签获取工作状态:

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

编辑 检查下面的代码并评论我们如何通过标签获取 WorkStatus。如果 WorkStatus 结果为空,则安排我们的工作。

 // 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
        }
    });

我没有测试过代码。请提供您的反馈。

希望这对您有所帮助。

于 2018-07-19T06:13:40.347 回答
0

我也在找同样的条件。我找不到。所以为了解决这个问题,我找到了一个机制。首先取消所有预定的工作,然后重新安排工作。这样我们就可以确保只维护您工作的一个实例。另外请确保您必须像这样维护您的工作代码逻辑。

取消工作。更多_

UUID compressionWorkId = compressionWork.getId();
WorkManager.getInstance().cancelWorkById(compressionWorkId);
于 2018-07-19T06:12:31.600 回答
0

保持相同的 taskIDExistingPeriodicWorkPolicy.KEEP不会每次都创建新任务。

 WorkManager.getInstance().enqueueUniquePeriodicWork(TASK_ID,
                ExistingPeriodicWorkPolicy.KEEP, work);
于 2020-07-22T06:20:24.807 回答