Existing 3-function callback to Kotlin Coroutines

前端 未结 2 1590
眼角桃花
眼角桃花 2021-01-30 02:19

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.op         


        
相关标签:
2条回答
  • 2021-01-30 02:42

    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)
        }
    

    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.

    0 讨论(0)
  • 2021-01-30 02:50

    I've used 2 solutions for this type of thing.

    1: wrap the interface in an extension

    CameraDevice.openCamera(cameraId: Integer, 
                    onOpenedCallback: (CameraDevice) -> (), 
              onDisconnectedCallback: (CameraDevice) ->()) {
    
        manager.openCamera(cameraId, object : CameraDevice.StateCallback() {
            override fun onOpened(openedCameraDevice: CameraDevice) {
                onOpenedCallback(openedCameraDevice)
            }
    
            override fun onDisconnected(cameraDevice: CameraDevice) {
                onDisconnectedCallback(cameraDevice)
            }
       })
    }
    

    2: Make a simple container class with a more functional interface:

    class StateCallbackWrapper(val onOpened: (CameraDevice) -> (), val onClosed: (CameraDevice) ->()): CameraDevice.StateCallback() {
        override fun onOpened(openedCameraDevice: CameraDevice) {
            onOpened(openedCameraDevice)
        }
    
        override fun onDisconnected(cameraDevice: CameraDevice) {
            onClosed(cameraDevice)
        }
    }
    

    Personally I would start with something like these, and then build whatever threading differences on top of that.

    0 讨论(0)
提交回复
热议问题