在uni-app uni-popup弹窗调用蓝牙相关事件会导致弹窗卡顿、无响应

在uni-app uni-popup弹窗调用蓝牙相关事件会导致弹窗卡顿、无响应

开发环境 版本号 项目创建方式
Mac 15.5 (24F74) HBuilderX

操作步骤:

  • 点击快速开始,会打开弹窗,进行蓝牙搜索。可重复进行打开、关闭弹窗进行测试。

预期结果:

  • 期望弹窗打开、关闭正常,可以适配市面上主流设备机型。

实际结果:

  • 弹窗打开、关闭卡顿,多次尝试后无响应。

bug描述:

  • 使用OPPO系列手机与华为畅享70(haronyos 4.0.0)手机,如果在uni-popup弹窗中调用蓝牙搜索等相关事件会导致弹窗关闭时卡断,如果多次调用弹窗的打开、关闭事件,弹窗会卡死、无响应。
  • 经过控制台打印发现,上述两种机型下,首次打开弹窗后,执行蓝牙初始化、搜素事件时,如果调用弹窗的关闭事件,受蓝牙事件影响无法立即关闭弹窗;并在弹窗延迟关闭后,再次打开弹窗,会出现卡顿;多次重复后,弹窗直接无响应。
  • ps:荣耀系列、ios设备无此异常。
  • 当前HBuilderX版本号下,默认package.json默认的"@dcloudio/uni-components":3.0.0-alpha-3000020210521001。怀疑是版本本过旧导致,已升级到"@dcloudio/uni-components": “3.0.0-4080720251210001”,仍无法解决问题。

更多关于在uni-app uni-popup弹窗调用蓝牙相关事件会导致弹窗卡顿、无响应的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

该bug反馈内容基本完整,标题清晰描述了问题核心,BUG描述详细说明了在OPPO和华为畅享70(HarmonyOS 4.0.0)设备上出现的弹窗卡顿现象,区分了正常设备(iOS/荣耀),并提供了版本信息(HBuilderX 4.66, @dcloudio/uni-components 3.0.0-4080720251210001)。但存在不足:缺少具体代码示例和错误日志截图,复现步骤过于简略(“点击快速开始”),无法直接复现问题。
经分析,该bug成立。知识库明确指出蓝牙搜索操作比较耗费系统资源,需在搜索后调用stopBluetoothDevicesDiscovery停止搜索。问题根源在于:在uni-popup弹窗中直接执行蓝牙搜索等耗时操作会阻塞UI线程,尤其在低端Android设备(如OPPO/华为畅享系列)上表现明显。多次开关弹窗未正确停止蓝牙搜索会导致资源累积,最终造成弹窗无响应。
这不是框架缺陷而是典型性能问题。解决方案:1) 弹窗关闭时必须调用stopBluetoothDevicesDiscovery;2) 将蓝牙操作封装在异步任务中避免阻塞UI;3) 参考uni-popup文档设置animation="false"减少动画开销。建议用户补充完整代码示例以便进一步诊断,同时注意Android设备碎片化特性导致的兼容性问题。 内容为 AI 生成,仅供参考

更多关于在uni-app uni-popup弹窗调用蓝牙相关事件会导致弹窗卡顿、无响应的实战教程也可以访问 https://www.itying.com/category-93-b0.html


针对你的回复我要补充一些信息: 1)弹窗关闭时已调用stopBluetoothDevicesDiscovery; 2) 已将蓝牙操作封装在异步任务中,使用async await调用相关蓝牙操作; 我尝试设置animation=“false”,从而减少动画开销,但是效果不佳。 请问还有没有更好的办法,解决我遇到的问题:部分设备上调用蓝牙操作会影响uni-popup的打开、关闭操作。

uni-popup 是一个前端组件, 不使用 uni-popup 的话,也会出现卡顿吗?

不使用 uni-popup 的话,不会出现卡顿。但在实际操作中,就像我给的图片里,打开弹窗,触发蓝牙初始化、搜索等事件,然后将搜索到蓝牙进行展示,这样就用到了uni-popup弹窗,涉及到了打开、关闭操作。

但是uni-popup是一个很常用的组件,除非万不得已,我肯定不会弃用它啊

问题可能源于蓝牙操作与弹窗动画在同一线程执行,导致UI阻塞。建议将蓝牙相关操作异步化处理,避免在弹窗生命周期中直接调用。

具体方案:

  1. 在弹窗打开前完成蓝牙初始化,或延迟蓝牙搜索操作。
  2. 使用 setTimeoutPromise 将蓝牙搜索与弹窗关闭逻辑分离。
  3. 检查蓝牙事件回调中是否有耗时操作,移至非UI线程执行。

示例代码调整:

// 弹窗关闭前停止蓝牙搜索
closePopup() {
  this.stopBluetoothScan(); // 先停止蓝牙操作
  setTimeout(() => {
    this.$refs.popup.close(); // 延迟关闭弹窗
  }, 50);
}
回到顶部