如何在绑定到 CameraX 分析器的执行器中添加延迟?



在我被覆盖的analyze()中,我需要在执行 IO 操作之前添加某种限制。如果没有限制,此操作会在每次调用analyze()时立即执行,并且实际上很快就会完成,但显然调用太快了,一段时间后相机预览会永久冻结(该应用程序仍在运行,因为 Logcat 不断显示新消息)。

我目前正在调查它是否与我的代码有关,例如忘记调用imageProxy.close()。到目前为止,一切似乎都很好,恐怕执行 IO 操作的设备会引发太多中断,CPU 无法处理,或者类似的事情。

我已经尝试了很好的旧Thread.sleep()但显然它会阻塞主线程并冻结 UI;我看过一些Handler#postDelayed()的例子,但我认为它没有做我想要的;我尝试将 IO 调用包装在一开始带有delay()的协程中,但同样我认为它没有做我想要的。基本上,我想从它执行的代码中调用Executor线程本身的某种形式的sleep()

一段时间后,相机预览会永久冻结

我已经看到此问题发生了很多次,通常是由于Analyzer未关闭的图像。即使不使用图像分析用例,您是否也看到了问题?

我已经尝试了很好的旧 Thread.sleep(),但显然它会阻止主线程并冻结 UI

这是为什么呢?如果你在Analyzer.analyze()内部添加对Thread.sleep()的调用,则不应该是这种情况,因为它会阻塞你在调用ImageAnalysis.setAnalyzer()时提供的Executor的线程,它不应该绑定到主线程。

执行分析次数较少的一种选择是将图像放入Analyzer内,如下所示:

private static final int ANALYSIS_DELAY_MS = 1_000;
private static final int INVALID_TIME = -1;
private long lastAnalysisTime = INVALID_TIME;
public void analyze (ImageProxy image) {
final long now = SystemClock.uptimeMillis();
// Drop frame if an image has been analyzed less than ANALYSIS_DELAY_MS ms ago
if (lastAnalysisTime != INVALID_TIME && (now - lastAnalysisTime < ANALYSIS_DELAY_MS)) {
image.close();
}
lastAnalysisTime = now;

// Analyze image
image.close();
}

还有一种方法,这就是我在本地项目中的做法。因此,在我的图像分析器中,我使用Handler#PostDelay重新绑定相机,这在预览中给出了一个小的黑屏,但它不会那么快地处理下一个图像。

我的用例是我必须连续扫描条形码,但扫描速度太快,并且多次扫描一个代码。所以,我只需要等待100毫秒。所以这对我有用。

try {
cameraProvider.unbindAll()
Handler(Looper.getMainLooper()).postDelayed({
cameraProvider.bindToLifecycle(
this, CameraSelector.DEFAULT_BACK_CAMERA, useCaseGroup.build())
}, 100)
}
catch(exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}

相关内容

最新更新