使用工作管理器每秒执行一次任务 API

Execute task every second using Work Manager API

工作管理器是一个新的 API,我尝试每秒执行一次任务,但它不起作用。

这是我的工人class

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)

它不起作用,因为两个周期性工作请求之间的最小间隔为 15 分钟,由 MIN_PERIODIC_INTERVAL_MILLIS 定义。

基于documentation

Creates a PeriodicWorkRequest to run periodically once every interval period. The PeriodicWorkRequest is guaranteed to run exactly one time during this interval. The intervalMillis must be greater than or equal to PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS. It may run immediately, at the end of the period, or any time in between so long as the other conditions are satisfied at the time.

我建议您避免如此频繁地安排工作。这最终会消耗更多资源并最终影响电池寿命。

WorkManager 并非设计为每秒 运行 个任务,因为它有两个选项来构建工作请求,即

  • PeriodicWorkRequest - 运行 每 15 分钟重复一次任务,即使我们将时间间隔更改为 < 15 分钟,默认情况下也只会 运行 持续 15 分钟。
  • OneTimeWorkRequest - 运行 秒一次

WorkManager 将排队工作请求将分别调用 Worker 类 到 运行 每个 workerclass 覆盖定义实际任务的 doWork() 的任务。

此方法在后台线程中 运行s,运行s 持续 10 分钟,之后工作人员停止。

因此,如果你想每秒安排任务 运行ning 更好的 运行 前台服务,或者如果你有 运行ning 短期任务。

如果您想 运行 长时间执行后台任务,最好避免它。

现在回答太晚了,但是, 工作管理器对于在周期性请求之间至少延迟 15 分钟的周期性时间安排任务很有用,但是如果您想以某种方式实现周期性工作,那么您可以使用下面给出的登录名来执行此操作,这不是一个好习惯,但它可以工作。

您可以将工作人员设置为使用 15 分钟请求的定期请求,这将定期工作,并且在工作人员中 class 您可以管理您的工作人员每秒,如下所示。

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 分钟后您的工作人员将再次发出请求,这就是您每秒完成工作的方式。 您必须管理您的工作人员何时停止,否则这也会造成内存泄漏。 这不是每秒都使用这种功能的最佳做法,但这是您可以实现此目的的方法。

实现该行为的另一种方法是创建 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();
    }
}