Android WorkManager 不会触发两个计划工作线程之一

2024-01-19

我的应用程序中安排了两个定期工作人员,其中一名工作人员在 24 小时后重复,另一名工作人员在 15 分钟后重复。

最初,在全新安装时,一切按预期工作,但几天后,我在 2 台设备(共 5 台)上遇到了问题。 24 小时工作人员被正确触发,但 15 分钟工作人员根本没有触发。我已经24小时监视这件事了。

我通过听诊器查看了workmanager的数据库,看到了一些24小时工人的条目和0个15分钟工人的条目。我正在寻找WorkSpec table.

我通过 Android studio 进行调试,并在使用查询 WorkManager 之后getWorkInfosByTag()我得到了 15 分钟工作人员的 80 个对象的列表,其中 79 个对象在CANCELED状态,其中一个处于ENQUEUED state.

显然,被取消的工人没有添加到数据库中?

我没有从谷歌找到任何解释工人被取消的场景的文档。

我在用1.0.0-beta03工作运行时的版本。 另外,我不会杀死该应用程序或做任何有趣的事情。该应用程序在后台运行并且没有被杀死。 设备为小米A2(Android 9)、红米Note 4(Android 7)。

我需要了解为什么工作人员被取消,是否有更好的方法来调试它?任何指示都会有帮助并点赞!

Thanks.

Edit1:发布代码来安排两个工作人员。

24小时定期工作人员:

public static synchronized void scheduleWork() {
    checkPreviousWorkerStatus();
    if (isWorking()) {
        Log.i("AppDataCleanupWorker", "Did not schedule data cleanup work; already running.");
        return;
    }

    if (lastWorkId != null) {
        WorkManager.getInstance().cancelAllWorkByTag("AppDataCleanupWorker");
        lastWorkId = null;
    }

    Constraints constraints = new Constraints.Builder()
            .setRequiresCharging(true)
            .build();

    PeriodicWorkRequest.Builder builder = new PeriodicWorkRequest
            .Builder(AppDataCleanupWorker.class, 24, TimeUnit.HOURS)
            .addTag("AppDataCleanupWorker")
            .setConstraints(constraints);

    PeriodicWorkRequest workRequest = builder.build();
    lastWorkId = workRequest.getId();
    WorkManager.getInstance().enqueue(workRequest);

    List<WorkInfo> workInfos = WorkManager.getInstance()
            .getWorkInfosByTagLiveData("AppDataCleanupWorker")
            .getValue();
    if (workInfos != null && workInfos.size() > 1) {
        throw new RuntimeException("Multiple workers scheduled. Only one schedule is expected.");
    }
}

15分钟周期性工作人员:

public static synchronized void scheduleWork() {
    checkPreviousWorkerStatus();
    if (isWorking) {
        Log.i("ImageUploadWorker", "Did not schedule image upload work; already running.");
        return;
    }

    if (lastWorkId != null) {
        WorkManager.getInstance().cancelAllWorkByTag("ImageUploadWorker");
        lastWorkId = null;
    }

    Constraints constraints = new Constraints.Builder()
            .setRequiresBatteryNotLow(true)
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build();
    PeriodicWorkRequest.Builder builder =
            new PeriodicWorkRequest.Builder(ImageUploadWorker.class, 15,
                    TimeUnit.MINUTES)
                    .addTag("ImageUploadWorker")
                    .setConstraints(constraints);
    PeriodicWorkRequest workRequest = builder.build();
    lastWorkId = workRequest.getId();
    WorkManager.getInstance().enqueue(workRequest);

    List<WorkInfo> workInfos = WorkManager.getInstance()
            .getWorkInfosByTagLiveData("ImageUploadWorker").getValue();
    if (workInfos != null && workInfos.size() > 1) {
        throw new RuntimeException("Multiple workers scheduled. Only one schedule is expected.");
    }
}

注意:设备已连接互联网且网速良好。


已解决:WorkManager 未触发 Worker

经过一番调试后解决了该问题。在这里发帖以防有人遇到同样的问题。

所以,我一次又一次地取消和排队工人。假设一个工作人员今天安排在上午 11.15 工作,然后我取消并再次排队,上午 11.15 的时段没有分配给新排队的工作人员。

相反,当使用上午 11.15 时隙时,工作管理器仅检查计划的工作线程是否已取消,并且不会触发新排队的工作线程。

这是我们测试的五分之三设备上的行为。在 2 台设备上,新排队的工作线程被正确触发。

现在解决方案:

  1. 删除所有代码来安排您的工作人员。

  2. In the onCreate()在您的应用程序中,首先调用pruneWork() on WorkManager删除所有堆积的已取消的工人计划。记住方法的返回值Operation这将帮助您检查删除的完成情况。 致电之前pruneWork()你也可以打电话cancelAllWorkByTag()让您的所有员工清理所有待处理的时间表。该方法还返回一个Operation.

  3. 清除工作经理日程后,您现在可以安排您的工作PeriodicWorkRequest你想要的方式。我用了enqueueUniquePeriodicWork()确保一次只有一个工作实例在运行。

现在,我的工作线程每 15 分钟就会被正确触发一次。

请注意,当您的设备睡眠并进入瞌睡模式时,这 15 分钟的持续时间将会增加。

您可以使用 Stetho 库检查工作管理器数据库。 表名是WorkSpec您可以在其中找到员工的所有时间表。您可以在某个断点处停止应用程序执行并使用getWorkInfosByTag() on WorkManager获取日程表及其当前状态的列表。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android WorkManager 不会触发两个计划工作线程之一 的相关文章

随机推荐

  • 转置没有聚合的行和列

    我有以下数据集 Account Contact 1 324324324 1 674323234 2 833343432 2 433243443 3 787655455 4 754327545 4 455435435 5 543544355
  • 如何在此 Builder 实现中摆脱 instanceof

    The idea 我需要创建命令 命令可以配置参数 并非每个命令都可以接收相同的参数 所以有些必须被忽略 我有一个抽象类 Command 其中定义了一个 Builder 默认情况下 每个附加参数都会抛出 UnsupportedOperati
  • 在 pandas 中使用带有元组列的查询

    我有一个 pandas df 其中一列作为元组 我想用query使用元组的第一个条目对 df 进行子集化 最好的方法是什么 我在 pandas 23 3 Python 3 6 6 MWE import pandas as pd df pd
  • Gitlab-ci.yml 创建合并请求

    我在 DEV 分支中运行以下 gitlab ci yml 文件 目标也为 DEV 由于我无法将 TARGET 指向 MASTER 因此不会自动创建 MR 我想知道是否可以在 gitlab ci 脚本本身中创建合并请求 dev stage d
  • 拉力赛中的速度图[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在开展一个项目 从拉力赛中提取数据并创建速度图表 我了解要使用的 REST Web 服务 API 是缺陷 迭代 分层需求和迭代累积
  • 具有 IDisposable 的无限状态机

    假设我有一个无限状态机来生成随机 md5 哈希值 public static IEnumerable
  • 使用 MongoDB 生成的 _ids 作为“秘密数据”(例如,OAuth 令牌)

    是 MongoDB id字段足够随机 不可猜测来充当秘密数据 例如 如果我正在构建服务器端 OAuth 我可以使用 id 作为用户的 OAuth 令牌吗 我想这样做是因为它为数据库提供了清洁性和可索引性 例如 tokens id gt oa
  • IntentService 中未调用 OnHandleIntent()

    我知道这个问题以前曾被问过 但我已经浏览了所有我能找到的答案 但仍然无法解决问题 问题是当 BroadcastReceiver 启动时 不会调用 IntentService onHandleIntent 奇怪的是 构造函数确实运行了 正如我
  • 将计算出的键添加到集合中

    请考虑这个由男人和女人组成的数据集 我根据几个变量在第二个时刻进行过滤 type ls JsonProvider lt gt let dt ls GetSamples let dt2 dt gt Seq filter fun c gt c
  • 处理 django 查询中的外来字符

    我正在构建从 GeoNames com 导入的城市名称搜索 有些城市的名称中带有国际字符 例如 伊斯坦布尔 实际上是数据库中的 伊斯坦布尔 当人们搜索 伊斯坦布尔 时 伊斯坦布尔不会出现 有没有一种方法可以在搜索中添加过滤器或解码器来知道
  • javascript从对象数组中获取键名称

    from data ja 大阪市 en Osaka 我想要得到 ja and en 我尝试了几种方法 data map function i return i 它返回 数字数组 console log Object keys Object
  • Espresso - 如何将 typeText 切换为英语或其他语言输入模式

    我正在使用 Espresso 来实现我的应用程序的自动测试框架 但在我设计的一些测试用例中 我发现我的测试总是失败 根本原因并不在于我对功能实现代码的测试代码 根本原因是在android输入法模式下 有时候 在中文输入模式下 我输入的文字是
  • jQuery .load 回调函数中 textStatus 参数的所有可能值是什么?

    我正在利用 jQuery 的回调函数 load http api jquery com load 方法来运行某些代码 如果textStatus的参数 loadmethod 等于某个字符串 例如我有 jQuery myContainer lo
  • VSCode 中具有语义突出显示的语言服务器

    我想写一个语言服务器VSCode具有语义突出显示支持 我使用的语言有非常复杂的规则 所以我不想依赖标记器来区分标识符和关键字 我已经在以下地区提供语言服务VS Community 我在那里编写了自己的分类器 可以编写自己的分类器VSCode
  • 在 OCR(光学字符识别)之前,您推荐使用什么软件进行图像增强? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我们目前正在研究在提交 OCR 之前提高图像质量的方法 我们当前使用的 OCR 引擎是 Nuance v15 的 Scansoft API
  • 使用 python 的多处理池和映射函数测量进度

    我用于并行 csv 处理的以下代码 usr bin env python import csv from time import sleep from multiprocessing import Pool from multiproces
  • 使用预定义的过滤器过滤 android ListView

    我想为 ListView 实现预定义的过滤器 我的 ListView 将包含数字 并且会有一个过滤器图标 单击该图标应显示 显示奇数 显示偶数 和 显示全部 等选项 如何在单击 过滤器 图标时显示弹出对话框 如果这是使用简单的弹出对话框实现
  • 使用 EmacsClient 创建带有文本的新缓冲区

    我有一个程序可以将文本发送到任何其他程序以进行进一步分析 例如 sed grep 等 我希望它将数据发送到 Emacs 并在那里进行分析 我该怎么做呢 EmacsClient 默认采用文件名 这是一个数据字符串而不是文件 我真的不想创建和删
  • PowerShell 远程处理序列化和反序列化

    用于从 PowerShell 序列化和反序列化对象 由 PowerShell Remoting 执行 的例程是否可用 我想避免将对象写入磁盘 使用 Export CliXML 并使用 Import CliXML 读回 基本上 我想获取反序列
  • Android WorkManager 不会触发两个计划工作线程之一

    我的应用程序中安排了两个定期工作人员 其中一名工作人员在 24 小时后重复 另一名工作人员在 15 分钟后重复 最初 在全新安装时 一切按预期工作 但几天后 我在 2 台设备 共 5 台 上遇到了问题 24 小时工作人员被正确触发 但 15