蓝牙搜索与设备发现是蓝牙操作的首要需求,下面是常见的封装实现:先启动搜索,再监听发现设备
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
success: () => {
uni.onBluetoothDeviceFound(res => {
console.log("startYasee =>", res);
});
}
});
上面可以打开搜索,并发现设备,不过这个有个比较坑的地方,当stopBluetoothDevicesDiscovery停止搜索时,由于没有关闭监听uni.onBluetoothDeviceFound的API,导致这个设备发现监听一直在内存中运行。可见一个帖子https://ask.dcloud.net.cn/question/183922
问题
1.多调用一次就多执行一次onBluetoothDeviceFound,从而多一次重复上报设备,而且上报时间是一样的,需要处理重复相同的上报,给程序带来处理压力
2.由于onBluetoothDeviceFound监听一直未关闭,多次监听在内存中导致程序占用过高,易导致程序卡顿。
解决方案
uni.onBluetoothDeviceFound只执行一次,通过uni.$emit和uni.$on实现发现的设备上报,下面是封装的实现
/**
* 开始搜寻蓝牙设备【核心】
* 此操作比较耗费系统资源,请在搜索并连接到设备后调用uni.stopBluetoothDevicesDiscovery方法停止搜索
* @param {Object} options 同官方配置选项
* @param {Function} callback 回调函数,设置则接收uni.onBluetoothDeviceFound发现设备
*/
export function start(options = {}, callback = () => {}) {
return new Promise((resolve, reject) => {
const discovery = function() {
return new Promise((resolve, reject) => {
options.allowDuplicatesKey = true; //是否允许重复上报同一设备,若未能获取advertisData则需要找开
options.success = res => {
if (callback) {
// uni.onBluetoothDeviceFound没有关闭监听API,所以使用uni.$emit和uni.$on来解决重复监听问题
// uni.onBluetoothDeviceFound(res2 => callback(res2));
found();
uni.$off("bluetooth-device-found");
uni.$on("bluetooth-device-found", res2 => callback(res2));
}
resolve(res);
};
options.fail = reject;
uni.startBluetoothDevicesDiscovery(options);
});
};
discovery().then(resolve).catch(reject);
});
}
// 通过uni.$emit和uni.$on来解决重复监听onBluetoothDeviceFound的问题
let foundable = false;
function found() {
if (!foundable) {
foundable = true;
uni.onBluetoothDeviceFound(res => uni.$emit("bluetooth-device-found", res));
}
}