当 onStopped 结束时,如何在我的 CoroutineWorker 中执行清理代码?

How can I execute cleanup code in my CoroutineWorker when onStopped is final?

我升级到 WorkManager 2.1.0 并尝试使用一些 Kotlin 扩展,包括 CoroutineWorker。我的工作人员之前扩展了 androidx.work.Worker,它正在通过覆盖 onStopped 来执行清理代码。为什么 onStoppedCoroutineWorker 中是最终的?在 CoroutineWorker 停止后,我还有其他方法可以执行清理代码吗?

根据 this blog post,这应该是一项功能吗?

您始终可以使用 job.invokeOnCompletetion,而不必依赖 CoroutineWorkeronStopped 回调。例如

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 文档:

Cancellable suspending functions throw CancellationException on cancellation which can be handled in the usual way. For example, try {...} finally {...} expression and Kotlin use function execute their finalization actions normally when a coroutine is cancelled. Coroutines documentation

这意味着您可以用通常的方式清理协程代码,Java/Kotlin 方法是 try 和 finally:

    override suspend fun doWork(): Result {
        return try {
            work()
            Result.success()
        } catch (e: Exception) {
            Result.failure()
        } finally {
            cleanup()
        }
    }

请注意,您不能在 catch 和 finally 中暂停。如果这样做,请使用 withContext(NonCancellable) NonCancellable documentation

赶上CancellationException

override suspend fun doWork(): Result {
    return try {
        // here do work
        return Result.success()
    } catch (e: CancellationException) {
        // here clean up
        return Result.failure()
    }
}