使用 Work Manager API 每秒执行一次任务
Posted
技术标签:
【中文标题】使用 Work Manager API 每秒执行一次任务【英文标题】:Execute task every second using Work Manager API 【发布时间】:2018-12-14 14:53:43 【问题描述】:Work Manager 是一个新的 API,我尝试每秒执行一次任务,但它不起作用。
这是我的工人阶级
class TestingWorker : Worker()
override fun doWork(): Result
Log.i("CheckWorker","Result here")
return Result.SUCCESS
这就是我叫它的地方。
val recurringWork: PeriodicWorkRequest = PeriodicWorkRequest.Builder(TestingWorker::class.java, 1, TimeUnit.SECONDS).build()
WorkManager.getInstance()?.enqueue(recurringWork)
【问题讨论】:
应用程序启动时只工作一次。但我想要的是我希望它每秒执行一次。 @VicJordan:明白了吗? 我猜最小时间间隔(和默认时间间隔)是 15 分钟。此外,不建议每秒运行 bg 任务,因为它可能不省电。 你说得对,兄弟。在尝试对此进行更多研究后,我得到了答案。 大家可以看看我的question 吗?请:) 【参考方案1】:它不起作用,因为两个周期性工作请求之间的最小间隔是 15 分钟,这是由 MIN_PERIODIC_INTERVAL_MILLIS 定义的。
基于documentation:
创建一个 PeriodicWorkRequest 以每隔一段时间定期运行一次 时期。 PeriodicWorkRequest 保证只运行一次 在此期间。 intervalMillis 必须大于或 等于 PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS。有可能 立即运行、在周期结束时或两者之间的任何时间运行 只要当时满足其他条件。
我建议您避免如此频繁地安排工作。这最终会消耗更多资源并最终影响电池寿命。
【讨论】:
我明白了。无论如何,它应该显示为警告消息,让我们知道它。 @Chivorn 是的!它确实在文档中明确指定。 我检查了源代码,发现如下: public void setPeriodic(long intervalDuration) if (intervalDuration @Chivorn 没问题。如果有用,请记住将答案标记为已接受,以便其他人也可以从中受益并享受编码:-)【参考方案2】:WorkManager 并非设计为每秒运行任务,因为它有两个选项来构建工作请求,即
PeriodicWorkRequest
- 每 15 分钟运行一次重复任务,即使我们将时间间隔更改为 anyhwere
OneTimeWorkRequest
- 运行一次
WorkManager 将排入队列,workrequests 将调用各自的 Worker 类来运行任务,其中每个 Worker 类将覆盖定义实际任务的doWork()
。
此方法在后台线程中运行并运行 10 分钟,然后工作程序停止。
因此,如果您想更好地安排每秒运行的任务,请使用运行前台服务,或者如果您在短时间内运行任务。
如果您想长时间运行后台任务,最佳做法是避免它。
【讨论】:
【参考方案3】:现在回答太晚了,但是, 工作管理器可用于在定期请求之间至少延迟 15 分钟的定期时间安排任务,但不知何故,如果您想实现定期工作,那么您可以使用下面给出的登录名来执行此操作,这不是一个好的做法,但它可以工作。
您可以将工作人员设置为具有 15 分钟请求的定期请求,该请求将定期工作,并且在工作人员类中,您可以按如下所示每秒管理您的工作人员。
override suspend fun doWork(): Result
for (i in 1..900)
delay(1000)
Log.d("Work for every second", "doWork: Running")
return Result.success()
这将每秒工作 15 分钟,15 分钟后,您的工作人员将再次发出请求,因此您可以通过这种方式实现每秒工作。 您必须管理您的工作人员何时停止,否则这也会造成内存泄漏。 这不是每秒钟都使用这种功能的最佳做法,但这就是您实现此目的的方法。
【讨论】:
【参考方案4】:实现该行为的另一种方法是创建 OneTimeWorkRequest
和该工作人员请求,在您想要的间隔内安排另一个初始延迟
setInitialDelay(5, TimeUnit.MINUTES)
例如
public class UploadWorker extends Worker
private final Context context;
public UploadWorker(
@NonNull Context context,
@NonNull WorkerParameters params)
super(context, params);
this.context = context;
@Override
public Result doWork()
Log.i("tracer:", "Worker executed");
// Indicate whether the work finished successfully with the Result
OneTimeWorkRequest mywork = new OneTimeWorkRequest.Builder(UploadWorker.class)
.setInitialDelay(5, TimeUnit.MINUTES)
.build();
WorkManager.getInstance(this.context).enqueue(mywork);
return Result.success();
【讨论】:
优秀,为我工作!以上是关于使用 Work Manager API 每秒执行一次任务的主要内容,如果未能解决你的问题,请参考以下文章
Android Work Manager:如何每月将作业排入队列