首页 > 解决方案 > Android 9 总是在 onStartJob 返回 true 后立即调用 onStopJob

问题描述

我有一个按如下方式实施的预定工作:

class RefreshImageService : JobService() {
    override fun onStartJob(params: JobParameters): Boolean {
        info { "RefreshImage: start job" }
        appCoroScope.launch {
            fetchImageAndUpdateWidget()
            info { "RefreshImage: finished" }
            jobFinished(params, false)
        }
        return true
    }

    override fun onStopJob(params: JobParameters): Boolean {
        info { "RefreshImage: stop job" }
        return true
    }
}

在日志中,我总是RefreshImage: stop job在之后立即看到RefreshImage: start job,然后,RefreshImage: finished这意味着 Android 立即释放了我的唤醒锁,并且我的服务被允许完成只是偶然的。如果 HTTP 请求花费更长的时间,它可能会被杀死。

这就是我声明服务的方式:

<service
    android:name=".RefreshImageService"
    android:permission="android.permission.BIND_JOB_SERVICE"
/>

这就是我安排它的方式:

val jobInfo = JobInfo.Builder(refreshImageJobId, 
        ComponentName(context, RefreshImageService::class.java))
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
    .setMinimumLatency(latencyMillis)
    .setOverrideDeadline(HOUR_IN_MILLIS)
    .build()
context.jobScheduler.schedule(jobInfo)

有什么我做错了,或者可能是让Android正常运行的解决方法?

标签: androidkotlinandroid-jobscheduler

解决方案


我意识到问题在于还必须根据当前 HTTP 结果fetchImageAndUpdateWidget()的标头来安排下一个图像获取。Last-Modified如果 Android 决定在我的作业到达调度代码之前终止它,我的作业将永远不会再次运行。

为了防止这种情况,我添加了一行在发出 HTTP 请求之前临时安排作业。然而,根据以下文档,这导致 Android 试图立即停止我目前的工作JobScheduler.schedule()

如果具有给定 ID 的作业当前正在运行,它将被停止。

这让我无法选择稳健地实现我的调度行为。我不得不求助于使用另一个预定的工作来检查我的主要工作是否失去了它的时间表。


推荐阅读