WorkManager 中唯一的 OneTimeWorkRequest [英] Unique OneTimeWorkRequest in Workmanager

查看:34
本文介绍了WorkManager 中唯一的 OneTimeWorkRequest的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用 OneTimeWorkRequest 在我们的项目中启动后台任务.

We are using OneTimeWorkRequest to start background task in our project.

  1. 在应用程序启动时,我们正在启动 OneTimeWorkRequest(比如 req A)
  2. 根据用户的操作,我们启动相同的工作请求 A.

在某些情况下,如果应用在工作请求 A 进行时被终止,Android 会在应用重启时自动重启请求 A.我们也再次启动请求 A.因此请求 A 的两个实例并行运行并导致死锁.

At some cases, if the app gets killed when the work request A is in progress, Android automatically restarts the request A when the app restarts. Once again we are also starting the request A again. So two instances of the request A runs in parallel and leads to a deadlock.

为了避免这种情况,我在 app start 中做了以下代码来检查工作程序是否正在运行,但这总是返回 false.

To avoid this, I did below code in app start to check if the worker is running but this always returns false.

public static boolean isMyWorkerRunning(String tag) {
        List<WorkStatus> status = WorkManager.getInstance().getStatusesByTag(tag).getValue();
        return status != null;
    }

有没有更好的方法来处理这个问题?

Is there a better way to handle this?

我检查了 beginUniqueWork().如果我只有一个请求,会不会更贵?

I checked the beginUniqueWork(). Is it costlier if I have only one request?

编辑 2:这个问题是关于独特的一次性任务.为了启动独特的周期任务,我们有一个单独的 API enqueueUniquePeriodicWork().但是我们没有用于开始独特的一次性工作的 API.我对在延续对象或手动检查和启动方法之间使用感到困惑.

Edit 2: This question is about unique One time task. For starting unique Periodic task we had a separate API enqueueUniquePeriodicWork(). But we did not have an API for starting unique onetime work. I was confused to use between continuation object or manually check and start approach.

在最近的版本中,他们 Android 为这个 enqueueUniqueWork() 添加了新的 api.这就是他们在发行说明中提到的确切原因.

In recent build they Android added new api for this enqueueUniqueWork(). This is the exact reason they mentioned in their release notes.

添加 WorkManager.enqueueUniqueWork() API 来排队唯一OneTimeWorkRequests 而无需创建 WorkContinuation.https://developer.android.com/jetpack/docs/release-notes

Add WorkManager.enqueueUniqueWork() API to enqueue unique OneTimeWorkRequests without having to create a WorkContinuation. https://developer.android.com/jetpack/docs/release-notes

推荐答案

Edit 2:

11 月 8 日发行说明:

Nov 8th release notes:

https://developer.android.com/jetpack/docs/release-notes

添加 WorkManager.enqueueUniqueWork() API 来排队唯一OneTimeWorkRequests 无需创建 WorkContinuation.

Add WorkManager.enqueueUniqueWork() API to enqueue unique OneTimeWorkRequests without having to create a WorkContinuation.

也就是说,alpha11 有这个新的 API 来唯一地排队一个一次性工作.

This says, alpha11 has this new API to uniquely enqueue a onetimework.

我尝试将代码更改如下:

I tried changing the code as follows:

OneTimeWorkRequest impWork = new OneTimeWorkRequest.Builder(WorkerNotesAttachment.class)
            .addTag(RWORK_TAG_NOTES)
            .build();
WorkManager.getInstance().enqueueUniqueWork(RWORK_TAG_NOTES, ExistingWorkPolicy.REPLACE, impWork);

<小时>

我尝试使用 beginUniqueWork API.但它有时无法运行.所以我最终编写了以下函数.


I tried using the beginUniqueWork API. But it fails to run sometimes. So I ended up writing the following function.

public static boolean isMyWorkerRunning(String tag) {
    List<WorkStatus> status = null;
    try {
        status = WorkManager.getInstance().getStatusesByTag(tag).get();
        boolean running = false;
        for (WorkStatus workStatus : status) {
            if (workStatus.getState() == State.RUNNING
                    || workStatus.getState() == State.ENQUEUED) {
                return true;
            }
        }
        return false;

    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return false;
}

我们需要获取所有 WorkStatus 对象并检查其中是否至少有一个处于运行或入队状态.由于系统将所有完成的工作在数据库中保留了几天(参考pruneWork()),我们需要检查所有工作实例.

We need to get all the WorkStatus objects and check if atleast one of them is in running or Enqueued state. As the system keeps all the completed works in the DB for few days (Refer pruneWork()), we need to check all the work instances.

在启动 OneTimeWorkRequest 之前调用此函数.

Invoke this function before starting the OneTimeWorkRequest.

public static void startCacheWorker() {

    String tag = RWORK_TAG_CACHE;

    if (isMyWorkerRunning(tag)) {
        log("worker", "RWORK: tag already scheduled, skipping " + tag);
        return;
    }
    // Import contact for given network
    OneTimeWorkRequest impWork = new OneTimeWorkRequest.Builder(WorkerCache.class)
            .addTag(tag)
            .build();
    WorkManager.getInstance().enqueue(impWork);
}

这篇关于WorkManager 中唯一的 OneTimeWorkRequest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆