refactor(serial): sendCmd 改用 Channel 保证串口写入顺序
- 新增 sendChannel(无界 Channel)作为发送队列 - openPort() 启动单一消费者协程顺序消费队列,避免并发写串口 - sendCmd() 改为 trySend() 入队,不再每次创建新协程 - release() 关闭 Channel,确保消费者协程正常退出 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import io.github.jeadyx.jserialport.SerialPortFactory
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -73,6 +74,9 @@ object ScaleManager {
|
||||
private var serialPort: AndroidSerialPort? = null
|
||||
private var scope = CoroutineScope(Dispatchers.IO)
|
||||
|
||||
/** 发送队列:保证串口写入顺序,避免并发写冲突 */
|
||||
private val sendChannel = Channel<String>(capacity = Channel.UNLIMITED)
|
||||
|
||||
/** 当前设备激活码,非空时收到激活请求自动应答 */
|
||||
private var activateCode: String = ""
|
||||
|
||||
@@ -141,6 +145,17 @@ object ScaleManager {
|
||||
parity = SerialPort.PARITY_NONE
|
||||
)
|
||||
} as AndroidSerialPort?
|
||||
// 启动单一消费者协程,顺序消费发送队列
|
||||
scope.launch {
|
||||
for (hexStr in sendChannel) {
|
||||
try {
|
||||
serialPort?.write(hexStr.hexToBytes())
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
log("发送命令失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@@ -301,7 +316,7 @@ object ScaleManager {
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 发送十六进制字符串指令(需先调用 init() 注入发送函数)
|
||||
* 发送十六进制字符串指令,指令进入发送队列按顺序写入串口
|
||||
*
|
||||
* @param hexStr 完整帧十六进制字符串,含协议头尾
|
||||
*/
|
||||
@@ -310,14 +325,7 @@ object ScaleManager {
|
||||
log("警告:ScaleManager 串口未打开或已释放")
|
||||
return
|
||||
}
|
||||
scope.launch {
|
||||
try {
|
||||
serialPort?.write(hexStr.hexToBytes())
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
log("发送命令失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
sendChannel.trySend(hexStr)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -423,6 +431,7 @@ object ScaleManager {
|
||||
* 通常在 Activity/Fragment 销毁或不再使用时调用
|
||||
*/
|
||||
suspend fun release() {
|
||||
sendChannel.close()
|
||||
scope.cancel()
|
||||
serialPort?.close()
|
||||
serialPort = null
|
||||
|
||||
Reference in New Issue
Block a user