android - 如何在工作管理器中管理 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 分钟之前我打开应用程序它会被调用。所以在这里我想检查任务是否没有运行,那么只有当我打开应用程序时它不应该执行
- 它还调用 wifiWorkBuilder(每 15 分钟执行一次的任务),每次打开应用程序时也会调用它。这两个任务完全不同并且不相互依赖,但是如果一个任务被调用,另一个任务也会在指定时间之前被调用。
上面的代码有什么问题。任何建议将不胜感激。谢谢
解决方案
几天前我遇到了同样的问题。我做到了——
如果 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时,它将返回 trueENQUEUED
。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
,如果您的每项任务都很重要,工作管理器将在完成后自动开始下一项工作。
推荐阅读
- windows - 批处理文件 FOR /F 循环中的 git --format 字符串有问题吗?
- react-native - 如何在循环中使用复选框以做出天真的反应
- java - 哪个内存效率更高?
- php - 有没有办法从字符串中修剪一个单词,如果它是一个重复的单词,而不是在没有重复的单词时修剪?
- c# - WPF C# 减少渲染时间,用于多用户控件布局
- r - 编写一个接受整数向量并返回逻辑向量的函数
- angular - Angular 7和firestore,从另一个集合中获取与另一个集合上的每个文档相对应的数据
- composer-php - php composer用例子解释最低稳定性
- c# - 使用 Table Per Hierarchy 模型设计 (MVCCore + EF 2.2) 为实体实现 REST API 的最佳建议
- android - 单击项目时播放列表查看特定歌曲?