kotlin协程(四)协程的挂起和恢复 --编写自己的挂起函数

115 阅读1分钟

定义自己的耗时任务适配协程

suspend fun corooutine() : String{
    // 返回suspendCancellableCoroutine方法包裹的耗时任务
    return suspendCancellableCoroutine { cancellableContinuation ->
        cancellableContinuation.invokeOnCancellation {
            //TODO 取消任务
        }
        //耗时任务
        TExecutor.execute(0){
            Thread.sleep(2000)
            TLog.d("ThreadEnd====")
            //耗时任务完成后,需要调用此方法恢复协程,让协程继续向下进行
            cancellableContinuation.resumeWith(Result.success("协成调用成功"))
        }
    }
}

主要是用suspendCancellableCoroutine方法来包裹耗时任务

public suspend inline fun <T> suspendCancellableCoroutine(
    crossinline block: (CancellableContinuation<T>) -> Unit
): T =
    suspendCoroutineUninterceptedOrReturn { uCont ->
        val cancellable = CancellableContinuationImpl(uCont.intercepted(), resumeMode = MODE_CANCELLABLE)
        /*
         * For non-atomic cancellation we setup parent-child relationship immediately
         * in case when `block` blocks the current thread (e.g. Rx2 with trampoline scheduler), but
         * properly supports cancellation.
         */
        cancellable.initCancellability()
        block(cancellable)
        cancellable.getResult()
    }

suspendCancellableCoroutine

在suspendCancellableCoroutine中 第 5 行构建了一个CancellableContinuationImpl类, 之后第 12 行包裹了需要运行的耗时代码块。第 13 行代码是重点,返回了cancellable.getResult()。这个我们第二节有解释,他会返回COROUTINE_SUSPENDED导致协成被挂起。

之后耗时方法内部调用cancellableContinuation.resumeWith 方法来恢复协成并返回结果,这个 resumeWith 方法之前的章节也说过