Java Android BLE:onCharacteristicRead()似乎已被线程阻止
我正在对一个可编程设备执行一系列特征读取。因为Java Android BLE:onCharacteristicRead()似乎已被线程阻止,java,android,multithreading,bluetooth-lowenergy,android-bluetooth,Java,Android,Multithreading,Bluetooth Lowenergy,Android Bluetooth,我正在对一个可编程设备执行一系列特征读取。因为readCharacteristic()是异步执行的,而且在发出另一个“read”调用之前,我们必须等待它完成,所以我使用了一个锁来wait(),然后在'onCharacteristicRead()中使用锁来再次运行 在调用readCharacteristic()之后,当我wait()时,我从未得到对onCharacteristicRead()的调用。如果我没有wait(),那么我确实会调用onCharacteristicRead(),并报告正确的值
readCharacteristic()
是异步执行的,而且在发出另一个“read”调用之前,我们必须等待它完成,所以我使用了一个锁来wait()
,然后在'onCharacteristicRead()
中使用锁来再次运行
在调用readCharacteristic()
之后,当我wait()
时,我从未得到对onCharacteristicRead()
的调用。如果我没有wait()
,那么我确实会调用onCharacteristicRead()
,并报告正确的值
以下是相关代码,它似乎阻止了对onCharacteristicRead()
的回调:
如果我只是删除上面的while()
语句,我就成功地获得了读取回调。当然,这阻止了我等待做进一步的阅读,所以我不能不等待就继续前进
既然readCharacteristic()
是异步的,为什么调用线程的执行与实际执行读取或调用回调的能力有任何关系
为了让事情更加混乱,我展示了一个toast,它在调用
readCharacteristic()
以及调用onCharacteristicRead()
时标识线程。这两个线程有不同的名称。我认为可能是由于某种原因在调用线程上调用了回调,但事实并非如此。那么线程是怎么回事?这里的问题似乎是一个关于线程的模糊问题,在我的原始帖子中看不到,因为我没有发布足够的调用历史记录来查看它。我会解释我在这里发现的东西,以防影响到其他人
导致我出现问题的完整通话记录如下:
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
doRead();
}
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
mBackgroundHandler.post(new Runnable() {
@Override
public void run() {
doRead();
}
).start();
}
discoverServices()
onServicesDiscovery()
doRead()
方法的地方readCharacteristic()
onCharacteristicRead()
onServicesDiscoveryd()
方法如下所示:
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
doRead();
}
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
mBackgroundHandler.post(new Runnable() {
@Override
public void run() {
doRead();
}
).start();
}
当执行doRead()
时,它将进入睡眠状态,因此会阻止执行。这会阻止回调方法完成,并且显然会阻塞整个可通信系统
第二个错误:
一旦我意识到上述问题,我将方法更改为:
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
new Thread(new Runnable() {
@Override
public void run() {
doRead();
}
).start();
}
据我所知,上述版本的方法应该可以工作。我正在创建一个运行doRead()
的新线程,因此睡在doRead()
中不会对BLE线程产生任何影响但确实如此此更改没有影响
-----------编辑注释--------------
在发布这篇文章之后,我真的无法解释为什么上面的匿名帖子不起作用。所以我又试了一次,这次它确实起作用了。不确定第一次出了什么问题,可能是我忘了在线程上调用start()
,或者其他什么
---------结束编辑注释------------
解决方案:
最后,我一时兴起,决定在实例化类时创建一个后台HandlerThread
(而不是在OnServicesDiscovery()
中旋转一个匿名Thread
)。该方法现在如下所示:
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
doRead();
}
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
mBackgroundHandler.post(new Runnable() {
@Override
public void run() {
doRead();
}
).start();
}
上述版本的方法有效。调用
doRead()
成功地在读取前一个特征时迭代每个特征。我通过添加以下代码解决了这个问题
@Override
public void onCharacteristicWrite(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
new Thread(new Runnable() {
@Override
public void run() {
gatt.readCharacteristic(characteristic);
}
}).start();
}
你能提供课程的完整来源吗?我也面临着类似的问题。提前感谢。您的
mBackgroundHandler
是如何初始化的?注意到同样的事情了!。在writeCharacteristic()上调试和中断时,它似乎总是能工作。我想这是同步问题。