首页 > 解决方案 > 如何在工作管理器中管理 2 个不同的 android 定期任务

问题描述

我想安排 2 个不同的定期任务,为此我正在使用工作管理器。1. 上传文件到服务器 - 每 20 分钟 2. 调用 API - 每 15 分钟

对于 API 调用(日常操作),以下是我的代码:

PeriodicWorkRequest.Builder dailyWorkBuilder =
            new PeriodicWorkRequest.Builder(CheckAccount.class, 15,
                    TimeUnit.MINUTES)
                    .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build());
    PeriodicWorkRequest DailyJob = dailyWorkBuilder.build();
    WorkManager.getInstance().enqueueUniquePeriodicWork("DailyJob", ExistingPeriodicWorkPolicy.REPLACE,DailyJob);

要上传文件,我使用以下代码:

PeriodicWorkRequest.Builder wifiWorkBuilder =
                        new PeriodicWorkRequest.Builder(FileUpload.class, 20,
                                TimeUnit.MINUTES)
                                .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build());
                PeriodicWorkRequest wifiWork = wifiWorkBuilder.build();
                WorkManager.getInstance().enqueueUniquePeriodicWork("wifiJob", ExistingPeriodicWorkPolicy.REPLACE,wifiWork);

现在在这里我面临两个困难: 1. 如果我打开应用程序 - 可以说在打开应用程序后我的 Activity 是 HomeActivity 在这个活动中我编写的 dailyWorkBuilder 代码(每 20 分钟后执行一次)每次打开应用程序时都会被调用。如果我没有打开应用程序,它将在 20 分钟后被调用,但在 20 分钟之前我打开应用程序它会被调用。所以在这里我想检查任务是否没有运行,那么只有当我打开应用程序时它不应该执行

  1. 它还调用 wifiWorkBuilder(每 15 分钟执行一次的任务),每次打开应用程序时也会调用它。这两个任务完全不同并且不相互依赖,但是如果一个任务被调用,另一个任务也会在指定时间之前被调用。

上面的代码有什么问题。任何建议将不胜感激。谢谢

标签: androidandroid-jetpack

解决方案


几天前我遇到了同样的问题。我做到了——

如果 Work-Manager 尚未安排,请安排工作。

在您设置工作的 MainActivity 中。

if(isWorkScheduled("DailyJob")){
  // now schedule DailyJob
}

我还问了一个问题并在得到解决方案后回答

private boolean isWorkScheduled(String tag) {
    WorkManager instance = WorkManager.getInstance();
    if (instance == null) return false;
    LiveData<List<WorkStatus>> statuses = instance.getStatusesByTag(tag);
    return statuses.getValue() != null && statuses.getValue().size() > 0;
}

如果您考虑以下方法,这取决于您。RUNNING当它的某些任务是or时,它将返回 true ENQUEUED

private boolean isWorkScheduled(String tag) {
    WorkManager instance = WorkManager.getInstance();
    if (instance == null) return false;
    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;
}

建议

  • 始终为空检查WorkManager对象,因为在某些情况下它可以为空。你可以看文档。
 * @return The singleton instance of {@link WorkManager}; this may be {@code null} in unusual
 *         circumstances where you have disabled automatic initialization and have failed to
 *         manually call {@link #initialize(Context, Configuration)}.
  • 使用ExistingPeriodicWorkPolicy.KEEP代替ExistingPeriodicWorkPolicy.REPLACE,如果您的每项任务都很重要,工作管理器将在完成后自动开始下一项工作。

推荐阅读