android - 在 CameraX analyze() 中执行异步代码的最佳方法是什么?
问题描述
我正在使用 CameraX 的图像分析用例,它在我的自定义类中不断调用该analyze()
方法。Analyzer
在内部analyze()
,在做任何其他事情之前,我需要向连接的设备发送请求并等待其响应;延迟非常低,我已经在同步进行,没有任何问题,但有人告诉我最好让它异步,以防设备响应太慢。
我知道 MLKit 的process()
返回 aTask<List<T>>
并且我已经调用onSuccessListener { }
了它,所以我想知道是否可以使用类似的方法(我不能Task<T>
从我的函数中返回 a,如何创建一个?)。否则你会建议线程、协程或其他东西吗?
编辑:下面有一个我正在尝试做的简化示例。对于相机发送的给定帧,我只需要在线执行当前分析,然后返回,以便analyze()
在下一帧再次调用它,它将在该帧上执行下一次分析。
它可能看起来很老套,但它适用于在单一用途设备(我们称之为Dev A)上连续在前台运行的应用程序,没有通过触摸或其他传统方式提供用户交互,因此它需要某种触发器来开始执行操作是必须的。
触发器也可能是当第一个图像分析成功时,但是整天从实时摄像机源运行 MLKit 或 TFLite 模型会使Dev A过热。到目前为止,最好的解决方案似乎是等待触发器来自独立运行的外部设备( Dev B )。
由于Dev B可能会延迟一些响应,因此我需要与它异步通信,因此首先提出问题的原因。虽然肯定有几个架构上的细微差别需要讨论,但问题的当前根源是我无法决定(或者更确切地说,我不知道)如何以非阻塞方式处理与Dev B的重复“连接” 。
我的意思是,我可以像其他需要多线程的情况一样对待这个问题,或者涉及相机的事实可能会带来额外的威胁吗?背压策略设置为STRATEGY_KEEP_ONLY_LATEST
,因此理论上如果当前调用analyze()
尚未完成,则新帧被丢弃并且即使在方法内部我仍在等待对Dev B的异步调用完成,也没有发生任何坏事,或者我错过了什么吗?
var connected = false
lateinit var result: Boolean
var analysis1 = true
var analysis2 = true
override fun analyze() {
if (!connected) {
result = connectToDevice() // needs to be async
connected = true
}
// need positive result to proceed, otherwise start over
if (!result) {
connected = false
return
}
if (analysis1) {
// perform analysis #1...
analysis1 = false
// when an analysis is done, exit early and perform next analysis on next frame
return
}
if (analysis2) {
// perform analysis #2...
analysis2 = false
// same as above
return
}
// when all analyses are done, reset all flags to start over
connected = false
analysis1 = true
analysis2 = true
}
解决方案
推荐阅读
- python - Printing the console to a log file is not reversible in Spyder for Python
- javascript - Android 应用程序与 WIX 网站上的assetlinks.json 链接
- powershell - 使用活动目录命令的 Powershell 在函数外部工作,但不在函数内部工作
- c# - C# 泛型类,但是如何?
- maven - 如何在 maven 项目中使用 smartics-jboss-modules maven 插件
- sqlite - Sqlite3,选择查询
- node.js - Angular 不支持的引擎
- amazon-web-services - 尝试使用pyspark从databricks连接到redshift数据库时出现空指针异常?
- python - 匹配固定列表和可变长度列表并根据固定列表返回二进制掩码
- python - 用 pandas DF 计算 ADX 指标/平滑平均问题