【问题标题】:Does CameraSource.stop() require to be called from UI Thread?CameraSource.stop() 是否需要从 UI 线程调用?
【发布时间】:2025-07-17 19:20:02
【问题描述】:

我正在开发一个使用 Mobile Vision 的 Google Barcode Scanner API 的 Android 应用。应用的目的是检测条形码,然后根据与条形码相关的数据采取一些行动。

一旦检测到第一个条码,我想停止摄像头源,以免继续检测。当我尝试在receiveDetections(Detector.Detections<Barcode> detections) 回调中执行cameraSource.stop() 时,线程被阻塞并且logcat 中有很多日志输出。由于此回调不在 UI 线程中执行,因此 UI 保持畅通。我尝试在 UI 线程中执行 cameraSource.stop() 并且效果很好。

我已经尝试从 UI 线程和另一个线程调用 cameraSource.start() 并且都可以正常工作。

现在我在文档中的任何地方都找不到与 cameraSource 的交互应该来自 UI 线程或工作线程的任何地方。我无法弄清楚从另一个线程调用时为什么会失败的逻辑。

【问题讨论】:

    标签: android multithreading camera barcode google-vision


    【解决方案1】:

    不必从 UI 线程调用 CameraSource.stop(),但由于实现细节,不应从执行 receiveDetections 的线程调用它。 stop() 代码等待该线程完成,因此以这种方式调用它会造成死锁。

    【讨论】:

    • 感谢您的回复,它更清楚了。我还查看了CameraSource 的来源here。但是,如果不是阻塞线程,而是将请求排队到处理receiveDetection() 的同一线程,那不是更有意义吗?一旦检测到第一个条形码,我真的不想使用标志来停止处理检测到的条形码。此外,如果从另一个线程调用stop(),检测器将继续不必要地检测,直到实际执行时间 stop()。
    • 目的是强制只有一个线程执行来自 CameraSource 的检测。如果不像现在的代码那样加入线程,客户端可能会在 CameraSource 上多次启动和停止,有时会导致多个线程同时执行检测。该线程将尽快停止,因为它在加入尝试之前被标记为不活动。