java – Android BLE:onCharacteristicRead()似乎被线程阻止

java – Android BLE:onCharacteristicRead()似乎被线程阻止,第1张

概述我正在针对BLE设备实现一系列特征读取.因为readCharacteristic()异步执行,并且因为我们必须等待直到完成才发出另一个“读”调用,所以我用了一个锁来等待()然后在’onCharacteristicRead()中我通知()锁,让事情再次发生. 当我等待()调用readCharacteristic()后,我从未得到onCharacteristicRead()的调用.如果我不等待(),那 我正在针对BLE设备实现一系列特征读取.因为readCharacteristic()异步执行,并且因为我们必须等待直到完成才发出另一个“读”调用,所以我用了一个锁来等待()然后在’onCharacteristicRead()中我通知()锁,让事情再次发生.

当我等待()调用readCharacteristic()后,我从未得到onCharacteristicRead()的调用.如果我不等待(),那么我会调用onCharacteristicRead()并且报告正确的值.

这是相关的代码似乎阻止对onCharacteristicRead()的回调:

private voID doRead() {    //....internal accounting stuff up here....    characteristic = mGatt.getService(mCurrServiceUUID).getCharacteristic(mCurrCharacteristicUUID);    isReading = mGatt.readCharacteristic(characteristic);    showToast("Is reading in progress? " + isReading);    showToast("On thread: " + Thread.currentThread().getname());    // Wait for read to complete before continuing.    while (isReading) {        synchronized (readLock) {            try {                readLock.wait();            } catch (InterruptedException e) {                e.printstacktrace();            }        }    }}public voID onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {    showToast("onCharacteristicRead()");    showToast("On thread: " + Thread.currentThread().getname());    byte[] value = characteristic.getValue();    StringBuilder sb = new StringBuilder();    for (byte b : value) {        sb.append(String.format("%02X",b));    }    showToast("Read characteristic value: " + sb.toString());    synchronized (readLock) {        isReading = false;        readLock.notifyAll();    }}

如果我只是删除上面的while()语句,我成功地得到读回调.当然,这阻止我等待进一步阅读,所以我不能等待前进.

由于readCharacteristic()是异步的,为什么执行调用线程与实际执行读取的能力有关,还是调用回调的能力?

为了使事情变得更加混乱,我会在调用readCharacteristic()时以及onCharacteristicRead()被调用时显示一个标识线程的吐司.这两个线程具有不同的名称.我以为可能是因为某些原因在调用线程上调用了回调,但是似乎并非如此.那么这里的线程是怎么回事?

解决方法 这里的问题似乎是一个晦涩的线程问题,它在我的原始帖子中看不到,因为我没有发布足够的通话记录来查看.我会解释我在这里找到的情况,以防其影响别人.

导致我问题的完整通话历史记录如下:

>启动Le Scan
>查找我关心的设备
>连接到设备的GATT服务器(返回一个GATT客户端,并且为所有异步通信呼叫提供一个BluetoothGattCallback)
>告诉GATT客户端发现服务()
>稍后,BLE系统调用我的回调函数onServicesdiscovered()
>现在我准备好开始阅读特征,因为服务数据被加载,所以这是我在原始帖子中调用doRead()方法的地方
>告诉GATT客户端读取特征()
>去睡觉,直到阅读完成
—-这是死锁发生的地方,但它应该是:
稍后,BLE系统调用我的callbacck的onCharacteristicRead()
>通知所有等待线程
>返回步骤7并重复

第一个错误:

本来我的onServicesdiscovered()方法看起来像这样:

public voID onServicesdiscovered(final BluetoothGatt gatt,int status) {    doRead();}

当doRead()执行时,它将进入休眠状态,从而阻止执行.这样可以防止回调方法的完成,并且显然对整个BLE通信系统进行了加油.

第二个错误:

一旦我意识到上述问题,我改变了以下方法:

public voID onServicesdiscovered(final BluetoothGatt gatt,int status) {    new Thread(new Runnable() {        @OverrIDe        public voID run() {            doRead();        }    ).start();}

据我所知,上述版本的方法应该可以工作.我正在创建一个新的线程来运行doRead(),所以睡在doRead()不应该对BLE线程有任何影响.但它确实!这种变化没有影响.

———–编辑笔记————–

发布后,我真的无法理解为什么上述匿名线程不起作用.所以我再试一次,这一次确实有效.不知道第一次出了什么问题,也许我忘了在线程或某事上调用start()

———结束编辑注————

解决方案:

最后,当我的类被实例化(而不是在onServicesdiscovered())上创建一个匿名Thread时,我决定创建一个后台HandlerThread.现在的方法如下所示:

public voID onServicesdiscovered(final BluetoothGatt gatt,int status) {    mBackgroundHandler.post(new Runnable() {        @OverrIDe        public voID run() {            doRead();        }    ).start();}

以上版本的方法有效.调用doRead()成功地遍历每个特征,因为前一个被读取.

总结

以上是内存溢出为你收集整理的java – Android BLE:onCharacteristicRead()似乎被线程阻止全部内容,希望文章能够帮你解决java – Android BLE:onCharacteristicRead()似乎被线程阻止所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1148524.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存