Kotlin 协程的现有 3 函数回调 [英] Existing 3-function callback to Kotlin Coroutines

查看:40
本文介绍了Kotlin 协程的现有 3 函数回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有具体示例的一般性问题:我想在拍照时使用 Kotlin 协程魔法而不是 Android 中的回调地狱.

I have a general question with a specific example: I'd like to use Kotlin coroutine magic instead of callback hell in Android when taking a picture.

manager.openCamera(cameraId, object : CameraDevice.StateCallback() {
    override fun onOpened(openedCameraDevice: CameraDevice) {
        println("Camera onOpened")
        // even more callbacks with openedCameraDevice.createCaptureRequest()....
    }

    override fun onDisconnected(cameraDevice: CameraDevice) {
        println("Camera onDisconnected")
        cameraDevice.close()
    }
    ...

我如何将其转换为不那么难看的东西?是否可以通过将主要流程指定为 promise-result 路径来获取具有三个左右函数的平均回调,并将其变成一个 promise-chain?如果那么,我应该/应该使用协程使其异步吗?

How would I convert that to something less ugly? Is it possible to take an average callback with three or so functions, and turn it into a promise-chain by designating the primary flow as the promise-result path? And if so, should/do I use coroutines to make it async?

我喜欢带有 async 和 .await 的东西,这会导致

I'd love something with async and .await that would result in

manager.open(cameraId).await().createCaptureRequest()

我正在尝试通过类似以下的方法来完成它,但我认为我没有使用 CompletableDeferred 对!

I'm trying to do it through something like the following, but I don't think I'm using CompletableDeferred right!

suspend fun CameraManager.open(cameraId:String): CameraDevice {
    val response = CompletableDeferred<CameraDevice>()
    this.openCamera(cameraId, object : CameraDevice.StateCallback() {
        override fun onOpened(cameraDevice: CameraDevice) {
            println("camera onOpened $cameraDevice")
            response.complete(cameraDevice)
        }

        override fun onDisconnected(cameraDevice: CameraDevice) {
            response.completeExceptionally(Exception("Camera onDisconnected $cameraDevice"))
            cameraDevice.close()
        }

        override fun onError(cameraDevice: CameraDevice, error: Int) {
            response.completeExceptionally(Exception("Camera onError $cameraDevice $error"))
            cameraDevice.close()
        }
    }, Handler())
    return response.await()
}

推荐答案

在这种特殊情况下,您可以使用通用方法通过 suspendCoroutine 函数将基于回调的 API 转换为挂起函数:

In this particular case you can use a general approach to convert a callback-based API to a suspending function via suspendCoroutine function:

suspend fun CameraManager.openCamera(cameraId: String): CameraDevice? =
    suspendCoroutine { cont ->
        val callback = object : CameraDevice.StateCallback() {
            override fun onOpened(camera: CameraDevice) {
                cont.resume(camera)
            }

            override fun onDisconnected(camera: CameraDevice) {
                cont.resume(null)
            }

            override fun onError(camera: CameraDevice, error: Int) {
                // assuming that we don't care about the error in this example
                cont.resume(null) 
            }
        }
        openCamera(cameraId, callback, null)
    }

现在,在您的应用程序代码中,您只需执行 manager.openCamera(cameraId) 并获取对 CameraDevice 的引用(如果它已成功打开或 null<)/code> 如果不是.

Now, in your application code you can just do manager.openCamera(cameraId) and get a reference to CameraDevice if it was opened successfully or null if it was not.

这篇关于Kotlin 协程的现有 3 函数回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆