android - 定期工作请求是否应该立即执行?

标签 android android-workmanager

编辑(TL;DR)

我没有意识到有多个构造函数用于定期工作请求。我感到困惑的线索是在已接受答案的评论中。

背景

我在安排工作时试图解决一些特殊情况。其中之一涉及立即开展工作,然后创建定期工作请求。我在Android的PeriodicWorkRequest documentation中找到了这个:

This work executes multiple times until it is cancelled, with the first execution happening immediately or as soon as the given Constraints are met.

我认为这意味着工作将在创建请求时执行。然而,这并不是我的测试实现中发生的情况。 (对于这项工作,不需要 CoroutineWorker 或网络连接约束,但它适用于我的业务需求,所以我正在测试它)

启动 worker

object WorkerManager {
    private val TAG = "WORKER_MANAGER_TEST"

    fun buildWorkRequest(
        startingNumber: Int,
        context: Context
    ) {
        val constraints =
            Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()

        val workRequest = PeriodicWorkRequest.Builder(
            PeriodicWorker::class.java,
            1,
            TimeUnit.HOURS,
            15,
            TimeUnit.MINUTES
        )
            .setInputData(
                workDataOf(Constants.INPUT_DATA_NUMBER to startingNumber)
            )
            .addTag(Constants.PERIODIC_WORKER_TAG)
            .setConstraints(constraints)
            .build()

        WorkManager.getInstance(context).enqueueUniquePeriodicWork(
            Constants.PERIODIC_WORKER_NAME,
            ExistingPeriodicWorkPolicy.REPLACE,
            workRequest
        )

        Log.d(TAG, "Worker started. Starting number: $startingNumber")
    }
}

worker :

class PeriodicWorker(context: Context, workerParams: WorkerParameters): CoroutineWorker(context,
    workerParams
) {
    companion object {
        var isInit = false
        var count: Int = 1
    }

    override suspend fun doWork(): Result = try {
        if (!isInit) {
            count = inputData.getInt(Constants.INPUT_DATA_NUMBER, Constants.DEFAULT_DATA_NUMBER)
            isInit = true
        } else {
            count += 1
        }

        Repository.updateNumber(count)

        Result.success()
    } catch (exception: Exception) {
        Result.failure()
    }
}

repo :

object Repository {
    private val TAG = "REPOSITORY_TAG"
    private val _number = MutableStateFlow(0)
    val number: StateFlow<Int> = _number

    suspend fun updateNumber(number: Int) {
        Log.d(TAG, "Number updated to: $number")
        _number.emit(number)
    }
}

ViewModel:

class NumberViewModel : ViewModel() {
    private val _count = MutableLiveData(0)
    val count: LiveData<Int> = _count

    init {
        viewModelScope.launch {
            Repository.number.collect {
                _count.postValue(it)
            }
        }
    } 
}

结果

我以 10 作为起始编号启动了一个工作程序。

日志:

8:45am  - Worker started. Starting number: 10
9:37am  - Number updated to: 10                 // work executed
10:37am - Number updated to: 11                 // work executed
11:37am - Number updated to: 12                 // work executed

设备信息

操作系统版本 28 -- 三星 SM-T390

我的结论

约束 - 不可能成为问题。在上述测试期间我有网络连接,这是唯一给定的约束。

电池优化 - 我确信在运行此测试之前该应用已被列入白名单。

因此,总而言之,PeriodicWorkRequests 似乎立即执行工作。 Android 文档应该改为:

This work executes multiple times until it is cancelled, with the first period beginning immediately. The first work execution then happens within the first flex interval given the constraints are met.

问题

我的结论看起来合理吗?还有什么我没有考虑到的吗?

最佳答案

你想多了。请转储 JS:

https://developer.android.com/topic/libraries/architecture/workmanager/how-to/debugging

使用adb shell dumpsys jobscheduler

然后检查转储中未满足的约束是什么:

  Required constraints: TIMING_DELAY CONNECTIVITY [0x90000000]
  Satisfied constraints: DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED WITHIN_QUOTA [0x3400000]
  Unsatisfied constraints: TIMING_DELAY CONNECTIVITY [0x90000000]

另外:

Minimum latency: +1h29m59s687ms

关于android - 定期工作请求是否应该立即执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69000226/

相关文章:

android - 在 map 中定位我的位置的问题

Android ZXING 通过 BitMatrix 编码 qr --> 存储到 byte[] --> 插入到数据库

android - setExpedited 是如何工作的,它和前台服务一样好和可靠吗?

android - 如何在 AsyncTask 的弹出窗口中打开 WebView

java - 用于检查未调用方法的注释

java - 在哪里可以找到 GmailContract 类?

android - 当应用程序在 Android 馅饼中被杀死时,检测网络状态并从后台上传视频数据(API 28)

java - WorkManager 自定义初始化提示 WorkManager#initialize

android - 工作经理适合这些情况吗?

android-workmanager - 当 onStopped 是 final 时,如何在我的 CoroutineWorker 中执行清理代码?