我没有意识到有多个构造函数用于定期工作请求。我感到困惑的线索是在已接受答案的评论中。
我在安排工作时试图解决一些特殊情况。其中之一涉及立即开展工作,然后创建定期工作请求。我在 Android 的 PeriodicWorkRequest documentation 中找到了这个:
此工作会执行多次,直到被取消,第一次执行会立即执行或在满足给定约束后立即执行。
我认为这意味着工作将在创建请求时执行。然而,这并不是我的测试实现中发生的情况。 (对于这项工作,不需要 CoroutineWorker 或网络连接约束,但它适用于我的业务需求,所以我正在测试它)
启动工人
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")
}
}
工人:
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()
}
}
回购:
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)
}
}
视图模型:
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 DO NOT 立即执行工作。 Android 文档应该说:
该工作会执行多次,直到被取消,第一个周期立即开始。如果满足约束,则第一个工作执行会在第一个弹性间隔内发生。
我的结论看起来合理吗?还有什么我没有考虑到的吗?
你想多了。请转储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
据我了解这个构造函数:
PeriodicWorkRequest.Builder(Class<? extends ListenableWorker> workerClass,
long repeatInterval, TimeUnit repeatIntervalTimeUnit,
long flexInterval, TimeUnit flexIntervalTimeUnit)
意味着你的工作将在
flexInterval
的
repeatInterval
内执行
默认情况下,定期工作请求会立即运行。您可以使用
在构建器中更改此设置.setInitialDelay(Duration)
.
如果您查看构建器的代码,您可以看到默认的
initialDelay
值为 0