You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免TabBar中just_audio出现PlayerInterruptedException(连接中止)异常

解决just_audio点击TabBar时抛出PlayerInterruptedException的问题

问题根源

点击TabBar切换标签页时,第一个标签页的Widget会被框架暂时销毁或标记为离屏状态,导致音频播放器的网络连接被强制中断,从而触发PlayerInterruptedException(Connection aborted)异常。滑动切换时框架的页面缓存策略不同,因此不会触发该异常。

具体修复方案

  1. 扩大异常捕获范围
    你目前仅在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")}";
  }
}
  1. 在播放控制方法中添加异常捕获
    如果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");
    }
  }
}
  1. 正确处理页面生命周期
    在第一个标签页的dispose()方法中释放播放器资源,避免后续残留连接引发异常:
@override
void dispose() {
  audioPlayer.dispose();
  super.dispose();
}

通过以上操作,即可完整捕获并忽略点击TabBar时触发的连接中断异常,不影响页面正常切换逻辑。

内容的提问来源于stack exchange,提问作者Flutter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:20:30