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

B W*_*B W 7 android-workmanager

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

根据这篇博客文章,这应该是一个功能吗?

小智 6

来自 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()
        }
    }
Run Code Online (Sandbox Code Playgroud)

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


Rah*_*hul 5

您可以随时使用job.invokeOnCompletetion,而不必依赖于onStopped回调CoroutineWorker。例如

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()
    }
}


Run Code Online (Sandbox Code Playgroud)