我有一个带有具体示例的一般性问题:我想在拍照时使用 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()
}
...
我怎样才能把它变成不那么难看的东西?是否可以采用三个左右函数的平均回调,并通过将主要流程指定为承诺结果路径,将其转变为承诺链?如果是这样,我应该/应该使用协程来使其异步吗?
我喜欢带有 async 和 .await 的东西,这会导致
manager.open(cameraId).await().createCaptureRequest()
我试图通过类似以下的方法来做到这一点,但我不认为我正在使用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()
}
在这种特殊情况下,您可以使用通用方法将基于回调的 API 转换为挂起函数:suspendCoroutine
功能:
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
如果不是的话。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)