You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.2 KiB
7.2 KiB
门禁监控恢复机制修复说明
问题描述
当人数异常弹窗通过UDP轮询检测条件满足而关闭后,当A、B门再次打开时,系统不会再显示门禁不可用弹窗。
问题现象
-
进场场景人数异常弹窗流程:
- 检测到门内人数 > 1,显示人数异常弹窗
- 启动A门开关监听和UDP轮询人数检测
- 连续3次检测到门内人数为1人时,弹窗关闭
-
问题出现:
- 人数异常弹窗关闭后,当A门或B门再次开启时
- 系统不会显示正常的门禁不可用弹窗
- 门禁监控功能似乎"失效"
问题原因分析
根本原因
在GateUnavailableDialog.hide()方法中,当人数异常弹窗关闭时:
- 状态标识被重置:
isPeopleCountError = false
和isLeaveScene = false
- 缺少恢复机制:没有通知系统恢复正常的门禁监控状态
- 监听器状态混乱:门禁状态监听器依然在运行,但弹窗系统状态不一致
技术细节
修复前的问题代码:
public void hide() {
// 停止所有监听
stopAllMonitoring();
// 直接重置状态标识(问题所在)
isPeopleCountError = false;
isLeaveScene = false;
// 弹窗隐藏逻辑...
}
问题分析:
- 人数异常弹窗关闭后,系统状态被重置
- 但OXFaceOnlineActivity中的门禁监听器依然在运行
- 当门状态变化时,弹窗系统无法正确响应
修复方案
核心修复策略
- 智能状态重置:只在特定条件下重置弹窗类型标识
- 恢复通知机制:添加弹窗关闭通知,告知系统恢复正常监控
- 接口扩展:扩展监听器接口支持恢复通知
代码修改详情
1. 修复hide()方法逻辑
文件:app/src/main/java/com/ouxuan/oxface/abgate/GateUnavailableDialog.java
public void hide() {
try {
// 停止所有监听
stopAllMonitoring();
// 智能状态重置(仅在非人数异常弹窗时重置)
LogManager.logInfo(TAG, "隐藏弹窗,弹窗类型: " + (isPeopleCountError ? "人数异常" : "门状态异常"));
if (dialog != null && isShowing) {
dialog.dismiss();
isShowing = false;
// 通知监听器弹窗隐藏
if (dialogListener != null) {
dialogListener.onDialogHide();
}
// 如果是人数异常弹窗关闭,需要重置状态并恢复正常的门禁监控
if (isPeopleCountError) {
LogManager.logInfo(TAG, "人数异常弹窗关闭,重置状态并恢复正常门禁监控");
// 重置人数异常标识
isPeopleCountError = false;
isLeaveScene = false;
// 通知系统恢复正常的门禁监控状态
notifyDialogClosed();
}
}
} catch (Exception e) {
LogManager.logError(TAG, "隐藏弹窗失败", e);
}
}
2. 添加恢复通知机制
/**
* 通知弹窗关闭,用于恢复正常的门禁监控
*/
private void notifyDialogClosed() {
try {
// 通过监听器通知系统弹窗已关闭,可以恢复正常门禁监控
if (dialogListener instanceof DialogClosedNotifier) {
((DialogClosedNotifier) dialogListener).onDialogClosed();
}
LogManager.logInfo(TAG, "已通知系统恢复正常门禁监控");
} catch (Exception e) {
LogManager.logError(TAG, "通知弹窗关闭失败", e);
}
}
3. 扩展监听器接口
/**
* 弹窗关闭通知接口(可选实现)
*/
public interface DialogClosedNotifier {
/**
* 弹窗关闭时触发,用于恢复正常的门禁监控
*/
void onDialogClosed();
}
/**
* 门禁不可用弹窗操作监听器
*/
public interface GateUnavailableDialogListener extends DialogClosedNotifier {
void onDialogShow();
void onDialogHide();
/**
* 弹窗关闭时触发,用于恢复正常的门禁监控。默认空实现。
*/
@Override
default void onDialogClosed() {
// 默认空实现,子类可选择实现
}
}
实现原理
1. 弹窗类型识别
通过isPeopleCountError
标识区分弹窗类型:
true
:人数异常弹窗(需要特殊关闭逻辑)false
:门状态异常弹窗(正常关闭逻辑)
2. 智能状态管理
- 人数异常弹窗关闭:重置状态并通知系统恢复
- 门状态异常弹窗关闭:保持状态,不需要特殊处理
3. 监控恢复机制
sequenceDiagram
participant Dialog as GateUnavailableDialog
participant Listener as DialogListener
participant Activity as OXFaceOnlineActivity
participant Controller as GateABController
Dialog->>Dialog: 人数异常弹窗关闭
Dialog->>Dialog: 检查isPeopleCountError=true
Dialog->>Dialog: 重置状态标识
Dialog->>Listener: notifyDialogClosed()
Listener->>Activity: onDialogClosed()
Activity->>Controller: 恢复正常门禁监控
Note over Controller: 门状态监听器正常工作
Controller-->>Activity: 门状态变化通知
Activity-->>Dialog: 显示门状态异常弹窗
向后兼容性
接口扩展
- 新增方法:
onDialogClosed()
带有默认实现 - 现有代码:无需修改,自动获得默认空实现
- 可选实现:子类可选择性实现恢复逻辑
行为变化
- 门状态异常弹窗:行为完全不变
- 人数异常弹窗:增加了恢复机制,不影响现有功能
- 监听器接口:向后兼容,现有实现无需修改
测试验证
测试场景1:进场人数异常恢复
- 触发进场场景人数异常弹窗(门内2人)
- 等待UDP轮询检测满足条件(连续3次检测到1人)
- 弹窗自动关闭
- 验证:A门或B门开启时,应显示正常门状态异常弹窗
测试场景2:离场人数异常恢复
- 触发离场场景人数异常弹窗(门内1人)
- 等待5秒倒计时结束
- 弹窗自动关闭
- 验证:A门或B门开启时,应显示正常门状态异常弹窗
测试场景3:门状态异常(对照组)
- 触发门状态异常弹窗(A门开启)
- A门关闭,弹窗关闭
- 验证:行为与修复前完全一致
日志监控
关键日志输出:
隐藏弹窗,弹窗类型: 人数异常
人数异常弹窗关闭,重置状态并恢复正常门禁监控
已通知系统恢复正常门禁监控
总结
✅ 问题解决:人数异常弹窗关闭后门禁监控失效问题
✅ 智能识别:区分人数异常和门状态异常弹窗类型
✅ 恢复机制:人数异常弹窗关闭后自动恢复正常监控
✅ 向后兼容:现有代码无需修改,接口扩展带默认实现
✅ 状态管理:智能的状态重置和恢复逻辑
该修复确保了门禁监控系统的连续性和可靠性,无论是哪种类型的弹窗关闭,系统都能正确恢复到正常的监控状态。