现有的Kotlin Coroutines的三功能回调 [英] Existing 3-function callback to Kotlin Coroutines
问题描述
我有一个带有特定示例的一般性问题:拍照时,我想使用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链? 因此,我应该/应该使用协程使其异步吗?
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
的引用(如果未成功打开).
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 Coroutines的三功能回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!