android - WorkManager - 定期运行作业的问题
问题描述
过去我使用AlarmManager
and aForegroundService
来定期运行作业。在我最近的应用程序中,我尝试改用 JetPack WorkManager
,但我无法让它可靠地工作。
我需要每天在预定义的时间运行一项工作(大约,电池优化很好),但在我的情况下,似乎一段时间后我的工作停止工作并且不再自动执行。
问题
如果我使用AlarmManager
and aForegroundService
我没有问题,我的工作会定期且可靠地执行。但是,如果我在WorkManager
下面尝试使用,该作业会执行几次,然后它会跳过或停止(例如,它不会在大多数时候在上午 8 点运行,而是在晚上 8 点运行;几天后它会完全停止)。
任何想法是什么问题?我正在我的 android 9 设备上对此进行测试...
附加信息
- 我的手机始终连接到互联网
- 我可以看到,即使我的手机在 20 点解锁并处于活动状态,这项工作也没有开始(几天后开始,一开始它可以工作)
代码
- 使作业入队的功能:
// 1) enqueue the periodic job
fun enqueuePeriodic(
context: Context,
keepNotification: Boolean
) {
val firstDelay = Util.getPeriodicImportFirstDelay()
val repeatInterval = Util.getPeriodicRepeatInterval()
val workManager = WorkManager.getInstance(context)
val data = workDataOf(
"keepNotification" to keepNotification
)
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val workRequest = PeriodicWorkRequest.Builder(
PaypalImportWorker::class.java,
repeatInterval.first,
repeatInterval.second
)
.setInitialDelay(firstDelay.first, firstDelay.second)
.setInputData(data)
.setConstraints(constraints)
.build()
workManager.enqueueUniquePeriodicWork(
"ImportWorker-PERIODIC",
ExistingPeriodicWorkPolicy.REPLACE,
workRequest
)
L.tag(TAG).d { "periodic work enqueued" }
}
- CoroutineWorker 类:
class PaypalImportWorker(appContext: Context, params: WorkerParameters) : CoroutineWorker(appContext, params) {
private val notificationManager = appContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
override suspend fun doWork(): Result {
L.tag(TAG).d { "Job started..." }
val keepNotification = inputData.getBoolean( "keepNotification", false)
// 1) create notification
val notification =
AppNotificationManager.createImportNotification(applicationContext, "Import started...")
// 2) make this a foreground job
val foregroundInfo = ForegroundInfo(AppNotificationManager.NOT_ID_IMPORTER, notification)
setForeground(foregroundInfo)
// 3) do work
val res = ...
// 4) notification
if (keepNotification) {
val not = ...
notificationManager.notify(AppNotificationManager.NOT_ID_IMPORTER_FINISHED, not)
}
L.tag(TAG).d { "Job finished (keepNotification: $keepNotification)" }
// 5) return result
return Result.success(
workDataOf(
"result" to res
)
)
}
private fun updateNotification(info: String) {
val notification = AppNotificationManager.createImportNotification(applicationContext, info)
notificationManager.notify(AppNotificationManager.NOT_ID_IMPORTER, notification)
}
}
- 定义和辅助函数
// DEFINITIONS - run checks, beginning at 20 o'clock every 12 hours
const val PERIODIC_CHECK_HOUR = 20
const val PERIODIC_CHECK_INTERVAL_HOUR = 12L
// HELPER functions
fun getPeriodicImportFirstDelay(): Pair<Long, TimeUnit> {
val currentDate = Calendar.getInstance()
val dueDate = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, Setup.PERIODIC_CHECK_HOUR)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
if (before(currentDate)) {
add(Calendar.HOUR_OF_DAY, 24)
}
}
val timeDiffInMillis = dueDate.timeInMillis - currentDate.timeInMillis
return Pair(timeDiffInMillis, TimeUnit.MILLISECONDS)
}
fun getPeriodicRepeatInterval(): Pair<Long, TimeUnit> = Pair(Setup.PERIODIC_CHECK_INTERVAL_HOUR, TimeUnit.HOURS)
解决方案
推荐阅读
- javascript - 当您按下“Enter”时,应在另一个元素的末尾创建一个元素
- flutter - 我使用 ADB 运行颤振应用程序,但该应用程序未显示在菜单中
- amazon-web-services - 无法测试基于 AWS Cognito 的用户注册和登录
- sql-server - SQL Server 到服务总线
- listview - SwiftUI:删除列表视图左右的空间?
- powershell - 在两个非常大的列表中查找不同之处
- node.js - 如何使用 API 路由在 Next.js 上下载文件
- c# - UWP - “System.IO.IOException:'网络访问被拒绝:'......”
- html - Shopify 上产品块的交替背景颜色?
- youtube - 具有自定义 URL 但 URL 中没有“c/” slug 的 YouTube 频道不会从 channels.list 端点返回 snippet.customUrl 道具