我有一个一般性的问题,下面是一个具体的例子:我想使用Kotlin协同程序魔术,而不是回调地狱在Android拍照时。
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()
}
...
我该如何将其转换为不那么难看的东西呢?***是否有可能将一个包含三个左右函数的普通回调函数,通过将主流指定为承诺-结果路径,将其转换为承诺-链?***如果有,我应该/应该使用协程使其异步吗?
我喜欢一些与异步和. waiting这将导致
manager.open(cameraId).await().createCaptureRequest()
我尝试通过类似下面的方法来实现它,但是我认为我没有正确使用CompletableDeferred
!
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()
}
3条答案
按热度按时间u4vypkhs1#
在这种特殊情况下,您可以使用一般方法通过
suspendCoroutine
函数将基于回调的API转换为挂起函数:现在,在应用程序代码中,您只需执行
manager.openCamera(cameraId)
,如果成功打开,则获取对CameraDevice
的引用,否则获取对null
的引用。yvgpqqbh2#
使用suspendCancellableCoroutine代替suspendCoroutine,并进行适当的异常处理
最好总是选择suspendCancellableCoroutine来处理协程作用域的取消,或者从底层API传播取消。Source with other great examples
06odsfpq3#
我用过两种方法来解决这种问题。
1:将接口 Package 在扩展中
2:创建一个具有更多功能接口的简单容器类:
就我个人而言,我会从这样的东西开始,然后在此基础上构建任何线程差异。