如何避免TabBar中just_audio出现PlayerInterruptedException(连接中止)异常
解决just_audio点击TabBar时抛出PlayerInterruptedException的问题
问题根源
点击TabBar切换标签页时,第一个标签页的Widget会被框架暂时销毁或标记为离屏状态,导致音频播放器的网络连接被强制中断,从而触发PlayerInterruptedException(Connection aborted)异常。滑动切换时框架的页面缓存策略不同,因此不会触发该异常。
具体修复方案
- 扩大异常捕获范围
你目前仅在load()阶段捕获了异常,但setUrl()操作本身也可能抛出该异常,且点击Tab时的连接中断可能发生在任意播放器操作环节。修改setAudioUrl方法,将setUrl也纳入try-catch块:
void setAudioUrl({required String url}) async { Duration? audioDuration; try { await audioPlayer.setUrl("$baseUrl/$url", initialPosition: Duration.zero); audioDuration = await audioPlayer.load(); } on PlayerInterruptedException catch (e) { // 直接忽略该异常,调试模式下可按需打印日志 if (kDebugMode) { print("忽略连接中断异常: $e"); } } catch (e) { // 可选:捕获其他未知播放器异常 if (kDebugMode) { print("其他播放器异常: $e"); } } if (audioDuration != null) { audioEndTime.value = "${audioDuration.inMinutes.remainder(60).toString().padLeft(2, "0")}:${audioDuration.inSeconds.remainder(60).toString().padLeft(2, "0")}"; } }
- 在播放控制方法中添加异常捕获
如果playAudio()方法直接调用了播放器的播放/暂停接口,同样需要添加异常捕获逻辑:
void playAudio() async { try { if (taskerProfileViewModel.isPlaying.value) { await audioPlayer.pause(); } else { await audioPlayer.play(); } taskerProfileViewModel.isPlaying.value = !taskerProfileViewModel.isPlaying.value; } on PlayerInterruptedException catch (e) { // 忽略异常并重置播放状态 taskerProfileViewModel.isPlaying.value = false; if (kDebugMode) { print("播放时连接中断,已忽略: $e"); } } }
- 正确处理页面生命周期
在第一个标签页的dispose()方法中释放播放器资源,避免后续残留连接引发异常:
@override void dispose() { audioPlayer.dispose(); super.dispose(); }
通过以上操作,即可完整捕获并忽略点击TabBar时触发的连接中断异常,不影响页面正常切换逻辑。
内容的提问来源于stack exchange,提问作者Flutter
相关产品推荐
相关产品推荐

