回调函数转协程通常使用两个协程相关的类:suspendCancellableCoroutine和suspendCoroutine,前者可以通过cancel()方法手动取消协程的执行,而suspendCoroutine没有该方法,调用cancel()后协程不再往下执行,抛出 CancellationException 异常,但是程序不会崩溃,这样会更加安全,通常推荐使用suspendCancellableCoroutine。
一、原始的回调方法
interface OnClickListener {
fun onConfirm(index: Int)
fun onCancel()
}
private fun method(listener: OnClickListener) {
thread {
Thread.sleep(3000)
listener.onConfirm(3)
}
}
private fun execute() {
method(object : OnClickListener {
override fun onConfirm(index: Int) {
Log.d("TAG", "onConfirm: $index")
}
override fun onCancel() {
Log.d("TAG", "onCancel: ")
}
})
}
二、使用协程
suspendCancellableCoroutine接收一个匿名函数,参数为CancellableContinuation,他继承自Continuation,最常用的三个方法resume,resumeWith和resumeWithException。
private suspend fun execute(): Int {
return suspendCancellableCoroutine {
method(object : OnClickListener {
override fun onConfirm(index: Int) {
if (it.isCancelled) {
return
}
it.resumeWith(Result.success(index))
}
override fun onCancel() {
it.resumeWith(Result.failure(Exception()))
}
})
}
}
使用:
lifecycleScope.launch{
val result = execute()
Log.d("TAG", "result: $result")
}