我升级到了WorkManager 2.1.0,并尝试使用一些 Kotlin 扩展,包括 CoroutineWorker
。我的 worker 以前是扩展自 androidx.work.Worker
的,并通过覆盖 onStopped
来执行清理代码。为什么 CoroutineWorker
中的 onStopped
是 final 的?是否有其他方式可以在 CoroutineWorker
停止后执行清理代码?
根据这篇博客文章,这是否应该是一项特性?
我升级到了WorkManager 2.1.0,并尝试使用一些 Kotlin 扩展,包括 CoroutineWorker
。我的 worker 以前是扩展自 androidx.work.Worker
的,并通过覆盖 onStopped
来执行清理代码。为什么 CoroutineWorker
中的 onStopped
是 final 的?是否有其他方式可以在 CoroutineWorker
停止后执行清理代码?
根据这篇博客文章,这是否应该是一项特性?
您可以始终使用job.invokeOnCompletion
,而无需依赖于CoroutineWorker
的onStopped
回调函数。例如:
import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
class TestWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
companion object {
private const val TAG = "TestWorker"
}
override suspend fun doWork(): Result {
return coroutineScope {
val job = async {
someWork()
}
job.invokeOnCompletion { exception: Throwable? ->
when (exception) {
is CancellationException -> {
Log.e(TAG, "Cleanup on completion", exception)
// cleanup on cancellations
}
else -> {
// do something else.
}
}
}
job.await()
}
}
suspend fun someWork(): Result {
TODO()
}
}
来自 Kotlin 文档:
可取消挂起函数在取消时会抛出 CancellationException 异常,可以按照通常的方式进行处理。例如,使用 try {...} finally {...} 表达式和 Kotlin 的 use 函数,在协程被取消时执行其最终化操作。 协程文档
这意味着您可以使用 try 和 finally 来清理协程代码,就像通常的 Java/Kotlin 一样:
override suspend fun doWork(): Result {
return try {
work()
Result.success()
} catch (e: Exception) {
Result.failure()
} finally {
cleanup()
}
}
只需捕获 CancellationException
异常即可。
override suspend fun doWork(): Result {
return try {
// here do work
return Result.success()
} catch (e: CancellationException) {
// here clean up
return Result.failure()
}
}