MTing 3 weeks ago
parent
commit
e78dbd6287
  1. 92
      app/src/main/java/com/ouxuan/oxface/device/Ox485.java

92
app/src/main/java/com/ouxuan/oxface/device/Ox485.java

@ -44,6 +44,9 @@ public class Ox485 {
private static final int MAX_RETRY_COUNT = 3; // 最大重试次数
private static final long RETRY_DELAY = 1000; // 重试延迟1秒
// 当前重试次数用于超时处理
private int currentRetryCount = 0;
// 单例实例
private static volatile Ox485 instance;
@ -158,28 +161,50 @@ public class Ox485 {
return;
}
// 使用重试机制执行通信
executeWithRetry(callback, 0);
}
/**
* 使用重试机制执行485通信
* @param callback 结果回调
* @param retryCount 当前重试次数
*/
private void executeWithRetry(PeopleNumCallback callback, int retryCount) {
currentRetryCount = retryCount; // 设置当前重试次数
LogManager.logInfo(TAG, "开始执行485通信 (重试次数: " + retryCount + "/" + MAX_RETRY_COUNT + ")");
try {
// 创建临时串口管理器
SerialPortManager serialPortManager = new SerialPortManager();
// 执行通信
sendCommandAndWaitResponse(serialPortManager, callback);
sendCommandAndWaitResponse(serialPortManager, callback, retryCount);
} catch (Exception e) {
String errorMsg = "485通信异常: " + e.getMessage();
LogManager.logError(TAG, errorMsg, e);
// 如果还有重试次数延迟后重试
if (retryCount < MAX_RETRY_COUNT) {
LogManager.logInfo(TAG, "485通信失败," + (RETRY_DELAY / 1000) + "秒后进行第" + (retryCount + 1) + "次重试");
mainHandler.postDelayed(() -> executeWithRetry(callback, retryCount + 1), RETRY_DELAY);
} else {
if (callback != null) {
mainHandler.post(() -> callback.onError(errorMsg));
}
}
}
}
/**
* 发送命令并等待响应采用即用即连模式
* @param serialPortManager 串口管理器实例
* @param callback 结果回调
* @param retryCount 当前重试次数
*/
private void sendCommandAndWaitResponse(SerialPortManager serialPortManager, PeopleNumCallback callback) {
private void sendCommandAndWaitResponse(SerialPortManager serialPortManager, PeopleNumCallback callback, final int retryCount) {
// 设置数据监听器
serialPortManager.setOnSerialPortDataListener(new OnSerialPortDataListener() {
@Override
@ -237,34 +262,58 @@ public class Ox485 {
String errorMsg = "485串口设备文件不存在: " + DEFAULT_SERIAL_PORT_PATH;
LogManager.logError(TAG, errorMsg);
closeAndCleanup(serialPortManager);
// 如果还有重试次数延迟后重试
if (retryCount < MAX_RETRY_COUNT) {
LogManager.logInfo(TAG, "串口文件不存在," + (RETRY_DELAY / 1000) + "秒后进行第" + (retryCount + 1) + "次重试");
mainHandler.postDelayed(() -> executeWithRetry(callback, retryCount + 1), RETRY_DELAY);
} else {
if (callback != null) {
mainHandler.post(() -> callback.onError(errorMsg));
}
}
return;
}
// 检查串口文件是否有读写权限
if (!serialPortFile.canRead() || !serialPortFile.canWrite()) {
String errorMsg = "485串口设备无读写权限: " + DEFAULT_SERIAL_PORT_PATH;
String errorMsg = "485串口设备无读写权限: " + DEFAULT_SERIAL_PORT_PATH +
" (可读:" + serialPortFile.canRead() + ", 可写:" + serialPortFile.canWrite() + ")";
LogManager.logError(TAG, errorMsg);
closeAndCleanup(serialPortManager);
// 如果还有重试次数延迟后重试
if (retryCount < MAX_RETRY_COUNT) {
LogManager.logInfo(TAG, "串口权限不足," + (RETRY_DELAY / 1000) + "秒后进行第" + (retryCount + 1) + "次重试");
mainHandler.postDelayed(() -> executeWithRetry(callback, retryCount + 1), RETRY_DELAY);
} else {
if (callback != null) {
mainHandler.post(() -> callback.onError(errorMsg));
}
}
return;
}
LogManager.logInfo(TAG, "串口文件状态正常: " + DEFAULT_SERIAL_PORT_PATH +
" (存在:" + serialPortFile.exists() + ", 可读:" + serialPortFile.canRead() +
", 可写:" + serialPortFile.canWrite() + ")");
// 配置串口参数
boolean openResult = serialPortManager.openSerialPort(serialPortFile, DEFAULT_BAUD_RATE);
LogManager.logInfo(TAG, "485串口打开结果: " + openResult);
if (!openResult) {
LogManager.logInfo(TAG, "485串口打开结果: " + openResult + " (路径:" + DEFAULT_SERIAL_PORT_PATH + ", 波特率:" + DEFAULT_BAUD_RATE + ")"); if (!openResult) {
String errorMsg = "打开485串口失败: " + DEFAULT_SERIAL_PORT_PATH;
LogManager.logError(TAG, errorMsg);
closeAndCleanup(serialPortManager);
// 如果还有重试次数延迟后重试
if (retryCount < MAX_RETRY_COUNT) {
LogManager.logInfo(TAG, "串口打开失败," + (RETRY_DELAY / 1000) + "秒后进行第" + (retryCount + 1) + "次重试");
mainHandler.postDelayed(() -> executeWithRetry(callback, retryCount + 1), RETRY_DELAY);
} else {
if (callback != null) {
mainHandler.post(() -> callback.onError(errorMsg));
}
}
return;
}
@ -284,9 +333,16 @@ public class Ox485 {
String errorMsg = "485命令发送失败,可能串口连接异常";
LogManager.logError(TAG, errorMsg);
closeAndCleanup(serialPortManager);
// 如果还有重试次数延迟后重试
if (retryCount < MAX_RETRY_COUNT) {
LogManager.logInfo(TAG, "命令发送失败," + (RETRY_DELAY / 1000) + "秒后进行第" + (retryCount + 1) + "次重试");
mainHandler.postDelayed(() -> executeWithRetry(callback, retryCount + 1), RETRY_DELAY);
} else {
if (callback != null) {
mainHandler.post(() -> callback.onError(errorMsg));
}
}
return;
}
@ -298,11 +354,18 @@ public class Ox485 {
LogManager.logError(TAG, errorMsg, e);
closeAndCleanup(serialPortManager);
// 如果还有重试次数延迟后重试
if (retryCount < MAX_RETRY_COUNT) {
LogManager.logInfo(TAG, "发送命令异常," + (RETRY_DELAY / 1000) + "秒后进行第" + (retryCount + 1) + "次重试");
mainHandler.postDelayed(() -> executeWithRetry(callback, retryCount + 1), RETRY_DELAY);
} else {
if (callback != null) {
mainHandler.post(() -> callback.onError(errorMsg));
}
}
}
}
/**
* 设置超时处理
@ -323,9 +386,15 @@ public class Ox485 {
// 超时后关闭连接
closeAndCleanup(serialPortManager);
// 如果还有重试次数延迟后重试
if (currentRetryCount < MAX_RETRY_COUNT) {
LogManager.logInfo(TAG, "查询超时," + (RETRY_DELAY / 1000) + "秒后进行第" + (currentRetryCount + 1) + "次重试");
mainHandler.postDelayed(() -> executeWithRetry(callback, currentRetryCount + 1), RETRY_DELAY);
} else {
if (callback != null) {
callback.onError(errorMsg);
}
}
};
timeoutHandler.postDelayed(timeoutRunnable, TIMEOUT_485_MILLIS);
@ -538,12 +607,23 @@ public class Ox485 {
private void closeAndCleanup(SerialPortManager serialPortManager) {
if (serialPortManager != null) {
try {
// 先停止读写线程
serialPortManager.stopReadThread();
serialPortManager.stopSendThread();
// 等待一小段时间确保线程停止
Thread.sleep(100);
// 关闭串口
serialPortManager.closeSerialPort();
LogManager.logInfo(TAG, "485串口已关闭并清理资源");
} catch (Exception e) {
LogManager.logError(TAG, "关闭485串口时发生异常: " + e.getMessage(), e);
}
}
// 强制清理超时任务
cancelTimeout();
}
/**

Loading…
Cancel
Save