当CoroutineWorker的onStopped是最终的时,我该如何执行清理代码?

15

我升级到了WorkManager 2.1.0,并尝试使用一些 Kotlin 扩展,包括 CoroutineWorker。我的 worker 以前是扩展自 androidx.work.Worker 的,并通过覆盖 onStopped 来执行清理代码。为什么 CoroutineWorker 中的 onStopped 是 final 的?是否有其他方式可以在 CoroutineWorker 停止后执行清理代码?

根据这篇博客文章,这是否应该是一项特性?

3个回答

10

您可以始终使用job.invokeOnCompletion,而无需依赖于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()
    }
}



我也在处理取消相关的工作。 - shubham1g5
这句话的意思是什么,“只需使用coroutineContext [Job]”?@Vlad - Yasir Ali
请问能否提供一些示例,以便查看如何使用coroutineContext[Job]? - Yasir Ali
非常有用,我会把这个加入到我的BaseCoroutineWorker类中。 - undefined

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

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

4

只需捕获 CancellationException 异常即可。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接