人脸识别运行时与会话重构变更记录

背景与问题

本次按 Android 人脸识别架构技能重新整理 SellWeight 的激活、初始化和识别启动链路。真机故障日志显示,选择人脸支付后应用并非正常返回首页,而是在百度人脸 native 库的 FaceAbilityTrack 链路发生 SIGSEGV,进程被系统重建后显示首页。故障前同时出现本地人脸数量为 0、搜索引擎未就绪,以及识别弹框重复初始化模型、数据库和内存索引的现象。

旧实现的问题包括:多个页面分别初始化人脸能力;弹框未等待索引就绪便打开摄像头;失败后启动首页并杀进程;连续帧可能并发进入 track 和活体/检索线程;索引 push 与 search 可能并发;弹框恢复和业务启动入口不统一。

新架构

1. 进程级 Runtime

新增 FaceRecognitionRuntimeFaceRuntimeCoordinator,按“在线激活(离线跳过)→业务模型→注册模型→本地数据库→1:N 内存索引”顺序初始化。Runtime 使用 UNINITIALIZEDINITIALIZINGREADYFAILED 四态,合并并发初始化,支持等待者取消与代际过滤,只保存 Application Context。

启动页只订阅 Runtime 最终结果;设置页激活、MQTT 和人员同步后的索引刷新也统一进入 Runtime,连续刷新通知会合并。

2. 单次识别 Session

新增 FaceRecognitionSessionFaceRecognitionSessionController。每个弹框的一次识别会话独立持有 Runtime 等待、摄像头、倒计时、代际、单帧门闩、单次终态和幂等释放。

Runtime 未就绪时不打开摄像头;本地人脸数量为 0 时提示先同步人员,不进入 native 识别。相机帧在异步使用前复制,旧会话和已销毁页面的迟到回调不会进入支付。

3. Native 调用串行化

FaceSDKManager.submitDetectCheck 在 track 或完整活体/检索链仍运行时拒绝下一帧。索引 push 不再中断正在执行的 native 更新;push 与 search 使用同一个 FaceSearch 锁,避免边检索边修改索引。

4. UI 与统一 Launcher

新增 FaceRecognitionLauncher,统一服务 MainActivityWeightActivityCookedFoodActivity,拦截状态已保存和重复弹框。

两个弹框仅渲染和转发用户操作,删除模型/数据库初始化与失败杀进程;在 onPause/onDestroyView 释放会话;增加无参恢复;Runtime 或人脸数据不可用时返回明确错误而不是误报超时。支付、订单、金额、人员 ID 和导航仍保留在 Activity。

自动化验证

真机验收边界

  1. 有本地人脸数据时,称重和熟食均可识别并进入原支付流程。
  2. 人脸数据为空时显示先同步人员,不打开识别链,不退出或返回首页。
  3. 连续进入、退出、重试时不崩溃、不重复弹框、旧结果不串入新订单。
  4. MQTT 人员变化触发索引刷新,刷新期间不崩溃,完成后可识别最新人员。
  5. 已初始化设备无网时复用本地授权、模型和人脸库。
  6. 主屏与客屏均正确关闭预览和提示。

本次未执行 Git 暂存、提交、推送、分支切换,也未在终端安装 APK。