我创建了一个简单的CoroutineWorker
,它运行1000次循环,延迟为1000毫秒。
此辅助进程是唯一的定期辅助进程,重复间隔为15分钟,并且ExistingPeriodicWorkPolicy
为KEEP
但当我启动工作器时,在执行一段时间后,工作器被取消,并出现异常JobCancellationException
完整例外:
Exception kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelling}@ba57765
12:55:47.088 WM-Wor...rapper I Work [ id=4c44c3da-3c57-4cac-a40a-82c948125807, tags={ com.sk.workmanagerdemo1.DownloadingWorker } ] was cancelled
java.util.concurrent.CancellationException: Task was cancelled.
at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1184)
at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:514)
at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:311)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
员工代码:
import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
import java.util.*
class DownloadingWorker(context: Context, params: WorkerParameters) :
CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return withContext(Dispatchers.IO) {
Log.i("MYTAG", "Started ${getCurrentDateTime()}")
return@withContext try {
for (i in 0..1000) {
delay(1000)
Log.i("MYTAG", "Downloading $i")
}
Log.i("MYTAG", "Completed ${getCurrentDateTime()}")
Result.success()
} catch (e: Exception) {
Log.i("MYTAG", "Exception $e")
Result.failure()
}
}
}
private fun getCurrentDateTime(): String {
val time = SimpleDateFormat("dd/M/yyyy hh:mm:ss")
return time.format(Date())
}
}
和工人的开始
private fun setPeriodicWorkRequest() {
val downloadConstraints = Constraints.Builder()
.setRequiresCharging(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val periodicWorkRequest = PeriodicWorkRequest
.Builder(DownloadingWorker::class.java, 15, TimeUnit.MINUTES)
.setConstraints(downloadConstraints)
.build()
WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork(
"DownloadWorker",
ExistingPeriodicWorkPolicy.KEEP,
periodicWorkRequest
)
}
我在Activity中单击按钮时调用上述函数。
我不知道为什么我会在10分钟后的一段时间后自动得到这个异常。
谢谢提前。请帮助我在这方面确定原因,并请让我知道任何输入从我这边。
2条答案
按热度按时间uajslkp61#
您是否已检查是否满足Internet权限所赋予的downloadConstraints变量中设置的约束,尝试使用PeriodicWorkRequest.Builder中的setInitialDelay()检查是否满足约束
lb3vh1jj2#
对我来说,我无法设法重现这个异常;尽管假设满足所有工作限制;在工作进程花费很长时间的情况下,存在由系统取消工作进程的可能性。
对于这种情况,文档提供了support for long-running workers,其关联前台服务,前台服务向系统/用户指示在后台存在长时间运行的处理;因此系统可以保持该进程,并且用户知道什么正在消耗他们的资源,并且这也可以允许他们停止该工作者。
尤其是当你提到它的长期与:
我不知道为什么我会在10分钟后的一段时间后自动得到这个异常。
文档中说了一些我认为可能是原因的东西:
WorkManager内置了对长时间运行的工作进程的支持。在这种情况下,WorkManager可以向操作系统提供一个信号,指示在执行此工作时应尽可能使进程保持活动状态。这些工作进程的运行时间可以超过10分钟。
要启用此功能,需要调用
startForeground()
来更新与前台服务关联的通知;通常随着工人的进步。文档中提供了一个示例,展示了如何在worker中使用它;在这里,我已经为您的
DownloadingWorker
自定义了它:确保将前台服务添加到
<application>
内的清单中:您还需要在API 33+和清单中以编程方式请求
Manifest.permission.POST_NOTIFICATIONS
: