本次调整以同级工程 yingeoai-sdk-restaurant-demo 的相机管理链路为基准,重点回收当前工程里相机生命周期被拆散后带来的状态不同步问题,覆盖以下场景:
DishRecognitionActivity 改回“暂停”和“释放”分离参考 demo 的相机页面和识别页面做法,当前页面生命周期调整为:
onResumeCameraStateListeneronPausestopCamera(...)pausePreview(...)onDestroystopCamera(...)这样做的目的,是让“临时离开页面”和“页面彻底销毁”有明确边界,避免一进一出页面后预览和 listener 状态脱节。
DishRecognitionActivity 启动预览前强制重新绑定相机连接回调当前工程的 CameraUsbUtils.stopCamera(...) 会清掉 cameraStateListener。
如果页面经历过一次完整 stop,再次进入时只调用 startCameraPreview(...),相机连接事件虽然还能发生,但页面层可能拿不到重新 attach 预览面的回调。
因此本次把 listener 绑定抽成 bindCameraStateListener(),并在以下时机统一补绑:
onResumestartCameraPreview()restartCameraPreview()这点是为了把页面行为重新拉回 demo 的“预览面和相机打开事件保持同一条链路”。
demo 的识别主流程在每次取帧后,都会先判断:
当前工程之前只看 isSdkInitDone,如果 SDK 服务断连,页面仍可能持续收到相机帧,但识别请求已经无法正常送达,表现为:
isPredictRunning 状态可能长时间不恢复本次在 DishRecognitionActivity 的后台识别线程里补上:
mYingeoAiSDK.checkBinderAlive()initAiSDK()这样行为和 demo 更接近,避免“相机正常但识别链路已断”的假运行状态。
NewDishLearningActivity 同步改为 pause / release 分离菜品学习页同样使用 CameraUsbUtils,如果一个页面按“暂停”处理,另一个页面仍在 onPause 直接 stopCamera(...),共享相机管理器的行为会继续不一致。
因此本次同步把 NewDishLearningActivity 的:
onPause -> stopCamera(...)改为:
onPause -> pausePreview(...)页面销毁时仍然保留 stopCamera(...),保证和识别页一致。
CameraUsbUtils.flipHorizontally() 里,非镜像分支之前只修改了 PreviewConfig 对象,但没有重新通过 setPreviewConfig(...) 下发,存在“关闭镜像不一定真正生效”的风险。
本次改为:
setPreviewConfig(...MIRROR_HORIZONTAL)setPreviewConfig(...MIRROR_NORMAL)这部分对应 demo 的镜像参数管理逻辑,补齐当前工程里遗漏的实际应用动作。
资源文件新增了 please_payment.mp3,本次将其接入 DishRecognitionActivity 的支付可用状态变更里:
autoPayReady == true 且未进入支付处理中时触发Constants.SETTING_VOICE_SWITCH这样可以避免识别结果持续刷新时反复连播,也不会在已经进入支付流程后再次提示。
本次修改后,相机相关行为预期如下:
已执行:
./gradlew :app:compileDebugJavaWithJavac
结果:BUILD SUCCESSFUL
如果还要继续向 demo 靠拢,下一步建议优先做两件事:
DishRecognitionActivity 当前叠加的“自动识别 / 自动支付 / 抽屉暂停”等业务状态机和相机状态机继续拆开,减少生命周期交叉影响。SettingsCameraFragment 的切相机、切分辨率、旋转、镜像变更也统一抽到共享的“重启预览入口”,避免每个页面各自兜底。