为什么WorkManager不会在我的应用关闭时运行我的任务?

4

即使我的应用程序关闭,我也希望能够执行一些定期工作。

根据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(如此处所建议的,感谢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)

我对限制条件进行了一些更改,如果您想知道为什么这与上面的代码不匹配,但问题仍然存在。

可能有一些非常基本的东西我忽略了,但我就是没看到。
我的问题:我需要做哪些更改才能确保我的定期工作实际上按周期执行?


1
你正在哪个设备上测试这个应用程序?如何测试?从Android Studio启动应用程序并不完全像从启动器启动它一样。此外,当您从最近的应用程序列表中滑出应用程序时,某些设备会强制停止应用程序。请查看如何调试WorkManager:https://developer.android.com/topic/libraries/architecture/workmanager/how-to/debugging - pfmaggi
请注意,ExistingPeriodicWorkPolicy.REPLACE 将会取消当前正在运行的 Worker(Coroutine 作用域也将被取消)。如果您只是想确保它正在运行,请考虑使用 ExistingPeriodicWorkPolicy.KEEP。另外,您正在使用哪个 WorkManager 版本? - pfmaggi
-使用Workmanager 2.4.0 -已切换到KEEP,之前进行了一些调试替换 -从Android Studio安装,从启动器启动(我想是的,会确认一下) -在OnePlus 7 Pro上运行(物理设备) -那个链接非常有帮助,需要一些时间来筛选生成的数据 :) - Joozd
1
请查看"Don't Kill my app"网站,了解OnePlus的限制情况: https://dontkillmyapp.com/oneplus您可以尝试调整这些设置,看看它们是否会有所不同。 - pfmaggi
谢谢,实际上是我的手机过于热心了,在停止后台工作方面! - Joozd
显示剩余2条评论
1个回答

3
我之前使用的代码运行得很好。问题出在我的一加手机阻止了后台任务的执行。这个链接 帮我找到了解决方案(设置 - 电池 - 电池优化 - 不对我的应用进行优化)。如果有必要,以后再考虑修复此问题。似乎这是一个适用于一加手机的特定问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接