检查是否已安排WorkManager

Khe*_*raj 9 android android-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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我把scheduleWork()onCreate()我的Application课.即使我可以通过这种方法检查我的服务是否正在运行.但我不希望安排WorkManager,如果它已经安排在计划时间内删除不一致.

喜欢

if(!workManagerIsScheduled())
   {
     scheduleWork();
   }
Run Code Online (Sandbox Code Playgroud)

有解决方案吗

Khe*_*raj 44

更新

如果您需要检查已经运行的工作管理器,只是因为您不想要重复工作.你可以简单地使用enqueueUniquePeriodicWork()

此方法允许您将唯一命名的PeriodicWorkRequest排入队列,其中一次只能激活特定名称的一个PeriodicWorkRequest.例如,您可能只希望一个同步操作处于活动状态.如果有一个待处理,您可以选择让它运行或用新工作替换它.

所以你不必担心作品的重复性.

 workmanager.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP , photoCheckWork);
Run Code Online (Sandbox Code Playgroud)
  • TAG是工作经理检查重复的唯一名称.
  • 您可以选择 ExistingPeriodicWorkPolicy.KEEPExistingPeriodicWorkPolicy.REPLACE.

Orignal Post

我没找到任何东西时创建了这个方法.

检查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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 检查instance.getWorkInfosByTag(tag)时总是返回空列表,所以我使用instance.getWorkInfosForUniqueWork(tag)在依赖项中工作正常 - &gt;实现“androidx.work:work-runtime:2.2.0” (5认同)

use*_*222 8

接受的答案是错误的(很糟糕,因为它默默地失败了)。这是正确答案

private boolean isWorkScheduled(String tag, Context context) {

        WorkManager instance = WorkManager.getInstance(context);
        ListenableFuture<List<WorkInfo>> statuses = instance.getWorkInfosByTag(tag);

        boolean running = false;
        List<WorkInfo> workInfoList = Collections.emptyList(); // Singleton, no performance penalty

        try {
            workInfoList = statuses.get();
        } catch (ExecutionException e) {
            Log.d(TAG, "ExecutionException in isWorkScheduled: " + e);
        } catch (InterruptedException e) {
            Log.d(TAG, "InterruptedException in isWorkScheduled: " + e);
        }

        for (WorkInfo workInfo : workInfoList) {
            WorkInfo.State state = workInfo.getState();
            running = running || (state == WorkInfo.State.RUNNING | state == WorkInfo.State.ENQUEUED);
        }
        return running;
Run Code Online (Sandbox Code Playgroud)

除了一些重构以避免误导多次返回之外,错误就在这一行

running = state == WorkInfo.State.RUNNING | state == WorkInfo.State.ENQUEUED;

如果您使用此行,您将仅获得最后评估的running。评论建议改用运算=|符。即使结果是正确的,代码也会不清楚并且(稍微)次优。 |是位运算符,||是逻辑运算符。我们要执行的操作是逻辑操作,而不是按位操作。在布尔值上,|||给出相同的结果,但只是||快捷方式,这是我们案例中的预期行为。

此代码至少适用于 WorkManager 2.5.0 和 2.6.0。


Irf*_*fan 6

1.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;
}
Run Code Online (Sandbox Code Playgroud)