camera X 被另一个 startFocusAndMetering 取消

camera X Cancelled by another startFocusAndMetering

我正在使用 cameraX 库实现自定义相机。我正在努力集中注意力,我做了以下事情

viewFinder.setOnTouchListener { v, event ->
            return@setOnTouchListener when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    true
                }
                MotionEvent.ACTION_UP -> {
                   // The below code is for focusing 

                    val factory = SurfaceOrientedMeteringPointFactory(
                        viewFinder.width.toFloat(),
                        viewFinder.height.toFloat()
                    )
                    val point = factory.createPoint(event.x, event.y)
                    try {
                        val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF)
                            .apply {
                                disableAutoCancel() //focus only when the user tap the preview
                            }.build()

                        val future = cameraControl?.startFocusAndMetering(action)
                        future?.addListener(Runnable {
--->line 66                 val result = future?.get()
                            println("log result ---> $result")
                        }, cameraExecutor)

                    } catch (e: CameraInfoUnavailableException) {
                        println("log error ---> $e")
                    }
                    true
                }
                else -> false // Unhandled event.
            }
        }

现在,它是一些聚焦我触摸的点的东西,它不是太准确,但没关系。并且在聚焦 5 到 6 次后应用程序崩溃并关闭。

FATAL EXCEPTION: pool-2-thread-1
...
...
java.lang.Error: java.util.concurrent.ExecutionException: androidx.camera.core.CameraControl$OperationCanceledException: Cancelled by another startFocusAndMetering()
...
...
...MainActivity$onCreate.run(MainActivity.kt:66)

我不明白为什么它会崩溃,而且它并不经常崩溃。有时会崩溃,有时不会。

编辑 1 :-

我了解到当我多次点击焦点时会发生这种情况。因此,在开始聚焦之前,如果正在进行,我需要清除之前的聚焦。但是,如何清除以前的焦点我没有得到。

编辑 2 :-

我试过这个 cameraControl?.cancelFocusAndMetering(),我只是把它放在 try 块的第一行。但问题仍然存在。

我刚刚删除了这个块

future?.addListener(Runnable {
          val result = future?.get()
          println("log result ---> $result")
       }, cameraExecutor)

它工作正常。但是不知道是对是错

有谁知道吗?请回答。目前我将其标记为有效的答案。

对此处的 java 代码表示歉意。但是根据我的经验,future?.get() 需要包裹在try中,catch

future.addListener(() -> {

    try
        {
            FocusMeteringResult result = (FocusMeteringResult) future.get();
            if(result.isFocusSuccessful())
            {
                // Focus has succeeded
            }
            else
            {
                // Focus has failed
            }
        }
        catch (ExecutionException e) // Thrown exceptions
        {
            e.printStackTrace();
        }
        catch (InterruptedException e) // Thrown exceptions
        {
            e.printStackTrace();
        }
}