前言
FlutterBlue
是Flutter
上最早的蓝牙插件库,为Flutter App提供蓝牙交互的能力,主要资料地址:
GitHub: https://github.com/pauldemarc...
Pub: https://pub.dev/packages/flut...
问题
FlutterBlue
的其他部分用起来都很好,代码显得非常易读。但是有一个问题一直伴随着FlutterBlue
的使用,在有的项目中,可以忽略这个问题,在有的项目中,这个问题会非常明显的造成逻辑问题,甚至造成整个项目出现问题,那就是重复收到回调问题。
详情
以下是FlutterBlue
文档提供的部分使用方法。
Connect to a device
// Connect to the device
await device.connect();
// Disconnect from device
device.disconnect();
Set notifications and listen to changes
await characteristic.setNotifyValue(true);
characteristic.value.listen((value) {
// do something with new value
});
如果你手动断开你的设备(断电或关闭蓝牙),再按上述代码连接,你会发现// do something with new value
处的代码会重复执行,这个问题非常的棘手,似乎限流函数都不对此处起作用。
解决
显然问题就发生在setNotifyValue
。在此处,FlutterBlue
会注册流,而在自动断开时,并不会取消这个监听,所以,我们需要手动监听device的状态,在断开连接时取消监听:
_connectListenControl = device.state.listen(
(BluetoothDeviceState newState) {
if (newState == BluetoothDeviceState.disconnected) {
// 取消之前的监听函数
_notifyListenControl?.cancel();
// 取消监听
_notify.setNotifyValue(false)
}
},
);
看上去似乎有一些反直觉:在设备断开后,还需要去操作设备,去取消设备的监听方法。
只能说这是FlutterBlue
本身的设计,这个设计的目的可能在于:在恢复连接时,恢复之前的监听。很显然通常的业务场景并不会设计恢复的操作,而是重新去建立新的连接,所以就造成了重复监听(因为之前的监听还在)。此时,应当手动释放监听。
结语
这也是一个比较顽固的问题,搞了一年才解决,之前都是放着不管。不过我认为这个问题也可能是多方面的,如果按此方法不能解决这个问题,请在评论区告诉我。
作者:马嘉伦
日期:2020/10/16
平台:Segmentfault,勿转载
我的其他文章:
【开发经验】Flutter组件的事件传递与数据控制
【开发经验】Flutter避免代码嵌套,写好build方法
【Flutter工具】fmaker:自动生成倍率切图/自动更换App图标
【Flutter工具】可能是Flutter上最简单的本地数据保存方案
【Flutter应用】Flutter精仿抖音开源
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。