Этот обработчик определяется в " callbackflow», который переопределяет функцию «handleMessage» и использует «trySend» для создания ByteArray.
Мне удалось отобразить полученные пакеты в реальном времени на компонуемый пользовательский интерфейс в виде шестнадцатеричных строк путем преобразования потока в SharedFlow в моем «источнике данных устройства Bluetooth» в StateFlow в моей ViewModel.
Я бы хотел, чтобы другие области моего приложения могли подписаться в SharedFlow и отфильтровывать пакеты, которые им интересны, но я также хотел бы иметь возможность последовательно запускать цепочки команд, не встраивая логику в пользовательский интерфейс.
Я подумал, что смогу добиться этого, создав функции приостановки, которые можно вызывать последовательно для выполнения ряда операций на внешнем устройстве. Например:
Отправить команду 1
Подождать ответа
Отправить команду 2
Подождать ответа
и т. д.
Я пытаясь понять, как они должны быть реализованы. По сути, я хочу инициировать отправку команды, а затем «прослушать» полученный поток пакетов на предмет правильного типа пакета, а затем вернуть пакет из функции приостановки.
Я новичок в Kotlin помимо того, что я довольно любитель в Android, поэтому я не уверен, что это «правильный» способ сделать что-то.
обработчик и поток обратного вызова выглядят следующим образом:
Код: Выделить всё
fun btInputStreamHandler(): Flow = callbackFlow {
val btMessageHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
val b = msg.data
val rxpacket = b.getByteArray("rxpacket")
if (rxpacket != null) {
//handleRxPacket(rxpacket)
trySend(rxpacket)
}
}
}
//this messageHandler is passed into the serial comms thread when a new device is connected
messageHandler = btMessageHandler
awaitClose {
messageHandler = null
}
}
val btInputPacketSharedFlow: SharedFlow = btInputStreamHandler()
.shareIn(CoroutineScope(Dispatchers.IO), SharingStarted.Eagerly)
Код: Выделить всё
suspend fun getValueFromBluetoothDevice(): ByteArray {
//this is the serial comms thread that loads packets to be sent asynchronously
btSerialProcess?.sendCommand(DeviceCommand.getParameter1())
var flag: Boolean = true
var result: ByteArray = ByteArray(0)
while( flag ) {
//Wait for flow to emit the correct packet type
result = btInputPacketSharedFlow
.filterNotNull()
.first()
if( DeviceCommand.getPacketType(result) == CORRECT_PACKET_TYPE ) {
flag = false
}
}
return result
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... ctions-and