在onStartJob返回true之后,Android 9始终会立即调用onStopJob

时间:2018-10-28 08:52:41

标签: android kotlin android-jobscheduler

我有一个预定的工作,实现如下:

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正常运行的解决方法?

1 个答案:

答案 0 :(得分:2)

我意识到问题出在fetchImageAndUpdateWidget()之内,它还必须处理基于当前HTTP结果的Last-Modified头调度下一个图像获取的问题。如果Android决定在到达计划代码之前取消我的工作,则我的工作将永远不会再次运行。

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

  

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

这使我无法可靠地实现我的调度行为。我不得不求助于使用另一个计划的工作,只是为了检查我的主要工作是否失去了计划。