【发布时间】:2020-11-17 21:07:04
【问题描述】:
即使我的应用程序关闭,我也想做一些定期工作。
根据WorkManager 文档:
WorkManager 旨在用于可延迟的工作——即不需要立即运行——并且即使应用退出或设备重新启动也需要可靠运行。
出于故障排除的目的,我创建了一个函数,它每小时调用一次我的服务器并告诉它给我发送一封电子邮件。
有问题的工作:
class TestMailWorker(appContext: Context, workerParams: WorkerParameters)
: CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
//Cloud.sendTestMail() opens a SSL connection to my server
//and sends some data which triggers my server to send an email:
return if (Cloud.sendTestMail()) Result.success() else Result.retry()
}
}
这会使我的服务器向我发送一封测试电子邮件。
它是从
fun scheduleTestMails(){
// TEST_EMAIL is a const val String to be used as a tag.
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val task = PeriodicWorkRequestBuilder<TestMailWorker>(Duration.ofHours(1)).apply {
setConstraints(constraints)
addTag(TEST_EMAIL)
}.build()
with (WorkManager.getInstance(App.instance)){
enqueueUniquePeriodicWork(TEST_EMAIL, ExistingPeriodicWorkPolicy.REPLACE, task)
}
}
这个计划函数是从我的主要App 类中调用的:
class App : Application(){
//(...)
override fun onCreate() {
super.onCreate()
//(...)
MyWorkersHub.scheduleTestMails()
}
}
当我的应用程序第一次启动时,我会收到一封电子邮件。如果我关闭应用程序(或重启手机等),我将不再收到电子邮件。
查看adb shell dumpsys jobscheduler(建议here,谢谢pfmaggi)我发现即使在杀死应用程序后,这份工作确实仍然存在。但是,即使所有迹象都在运行,它也不会执行:
JOB #u0a407/1959: 2c4f52a nl.mydomain.myapp/androidx.work.impl.background.systemjob.SystemJobService
u0a407 tag=*job*/nl.mydomain.myapp/androidx.work.impl.background.systemjob.SystemJobService
Source: uid=u0a407 user=0 pkg=nl.mydomain.myapp
JobInfo:
Service: nl.mydomain.myapp/androidx.work.impl.background.systemjob.SystemJobService
Requires: charging=true batteryNotLow=false deviceIdle=false
Extras: mParcelledData.dataSize=180
Network type: NetworkRequest [ NONE id=0, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&VALIDATED Uid: 10407] ]
Minimum latency: +15m59s958ms
Backoff: policy=1 initial=+30s0ms
Has early constraint
Required constraints: CHARGING TIMING_DELAY CONNECTIVITY [0x90000001]
Satisfied constraints: CHARGING BATTERY_NOT_LOW TIMING_DELAY CONNECTIVITY DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED WITHIN_QUOTA [0x93400003]
Unsatisfied constraints:
Tracking: BATTERY CONNECTIVITY TIME QUOTA
Implicit constraints:
readyNotDozing: true
readyNotRestrictedInBg: true
Network: 143
Standby bucket: ACTIVE
Enqueue time: -33m32s112ms
Run time: earliest=-17m32s165ms, latest=none, original latest=none
Last run heartbeat: 0
Ready: false (job=true user=true !pending=true !active=true !backingup=true comp=true)
(我对限制做了一些更改,以防您想知道为什么这与上面的代码不匹配,但问题仍然存在)
我可能缺少一些非常基本的东西,但我只是没有看到它。
我的问题:我需要更改什么以确保我的定期工作实际上是定期执行?
【问题讨论】:
-
您在哪个设备上测试这个以及如何测试?从 Android Studio 启动应用程序与从启动器启动应用程序不同。此外,当您从最近的应用程序列表中滑出某个应用程序时,某些设备会强制停止该应用程序。看看如何调试WorkManager:developer.android.com/topic/libraries/architecture/workmanager/…
-
还要记住 ExistingPeriodicWorkPolicy.REPLACE 将取消当前正在运行的 Worker(协程范围将被取消)。如果您只需要确保它正在运行,请考虑使用 ExistingPeriodicWorkPolicy.KEEP。另外,您使用的是哪个 WorkManager 版本?
-
- 使用 Workmanager 2.4.0 - 切换到 KEEP,正在替换一些早期的调试 - 从 Android Studio 安装,从启动器启动(我认为,会确保) - 在 OnePlus 7 上运行Pro(物理设备)-该链接很有帮助,需要一些时间来筛选生成的数据:)
-
查看关于 OnePlus 限制的 Don't Kill my app 网站:dontkillmyapp.com/oneplus 您可以尝试使用这些设置,看看它们是否有所作为。
-
另外github.com/judemanutd/AutoStarter 可能会有所帮助,我还没有测试过。
标签: android kotlin android-workmanager