gpt4 book ai didi

android - 如何通过读/写 BLE Gatt 特性实现最大的线程安全性?

转载 作者:塔克拉玛干 更新时间:2023-11-02 18:59:40 24 4
gpt4 key购买 nike

我正在与 BLE 设备通信,该设备通过一个特性向我发送大量数据。相同的特性用于向设备发送数据。

在 Androids BluetoothGattCharacteristic 里面有方法

public byte[] getValue() {
return mValue;
}

public boolean setValue(byte[] value) {
mValue = value;
return true;
}

但是,执行发生在不同的线程中。 Android 运行大约 5 个不同的 Binder 线程,它们调用

onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic 特征)

我现在尝试获取数组作为回调中的第一个操作,但不能保证另一个线程(不受我控制)同时设置数组。

虽然上面似乎可以解决问题,但更复杂的问题是“针对传入的数据流”发送数据。

我必须使用相同的特性将数据向下发送到设备,所以我 setValue() 然后是 BluetoothGatt.writeCharacteristic

public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
// some null checks etc

//now it locks the device
synchronized(mDeviceBusy) {
if (mDeviceBusy) return false;
mDeviceBusy = true;
}

//the actual execution

return true;
}

然后我会在某个时刻收到来自某个线程的回调

onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) 

但是,当我获取该值并尝试检查它是否是我想要发送的内容时,有时它已经是一个刚刚从其他线程更新的接收包。

如何在不访问 Android BLE API 或堆栈等的情况下使其更加线程安全?

最佳答案

在 SDK27 中,onNotify() BluetoothGatt.java 中的回调函数已更新为同时调用 BluetoothGattCharacteristic.setValue()BluetoothGattCallback.onCharacteristicChanged()Runnable 的 run() .

此更改允许我们强制所有调用 BluetoothGattCharacteristic.setValue() - 我们对特性的出站写入和入站通知都在同一个线程上,这消除了破坏 BluetoothGattCharacteristic.mValue 的竞争条件。 ;

  1. 创建 HandlerThread
  2. 创建 Handler附在你的HandlerThread
  3. 传递您的 Handler进入BluetoothDevice.connectGatt() - 恭喜,收到通知时 setValue()onCharacteristicChanged()将在您的 HandlerThread 上被调用.
  4. 当您想写入特征时,发布您的 setValue()writeCharacteristic()给你的HandlerThread通过你的处理程序

现在所有参与竞争条件的函数调用都在同一个线程上执行,消除了竞争条件。

关于android - 如何通过读/写 BLE Gatt 特性实现最大的线程安全性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38922639/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com