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

Flutter中audio_service与just_audio在iOS端导航跳转后无法播放问题

问题原因及解决方案

核心原因

  • audio_service 初始化时机错误:绝大多数这类场景是你把 AudioService.init() 方法放在了播放页的 initState 生命周期中执行。首次直接打开播放页时全局还没有注册过 AudioHandler,初始化正常;当从播放页 pop 回首页后,旧的 AudioHandler 实例没有完全销毁,再次 push 播放页时重复执行初始化逻辑,iOS 端原生侧的音频服务通信通道会出现注册冲突,导致 just_audio 的加载请求无法正常传递到原生层,始终处于缓冲状态。
  • 音频资源未主动释放:播放页 dispose 时没有主动销毁 AudioPlayer 实例、停止并释放 AudioHandler 资源,Android 侧有自动资源回收机制可以兼容这种情况,但 iOS 端的 AVAudioSession 对资源占用管控更严格,旧实例未释放的情况下新实例无法抢占音频会话使用权,加载请求会被系统挂起。
  • 加载触发时机过早:你在播放页 initState 中直接调用音频加载方法,此时 Flutter 路由跳转动画还未完成,播放页还未完全处于前台活跃状态,iOS 系统会默认抑制非活跃页面的音频加载请求,导致加载一直没有响应。

修复方案

1. 全局初始化 audio_service

将 AudioService.init() 逻辑移到 main.dart 的 main() 方法中,APP 启动时全局完成初始化,不要放在单个页面中执行:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 全局初始化audio_service
  final audioHandler = await AudioService.init(
    builder: () => MyAudioHandler(),
    config: const AudioServiceConfig(
      androidNotificationChannelId: 'com.yourapp.audio',
      androidNotificationChannelName: 'Audio Playback',
      iosNotificationCategoryIdentifier: 'com.yourapp.audio',
    ),
  );
  runApp(MyApp(audioHandler: audioHandler));
}

全局实例通过 Provider 或者 GetIt 等状态管理工具传递到各个页面使用,避免重复初始化。

2. 主动释放页面音频资源

在播放页的 dispose 生命周期中主动释放当前页面占用的音频资源:

@override
void dispose() {
  // 停止当前播放
  audioHandler.stop();
  // 销毁当前页面绑定的AudioPlayer实例(如果是页面内创建的)
  player.dispose();
  super.dispose();
}

3. 调整音频加载触发时机

将音频加载逻辑放在路由跳转完成后的帧回调中执行,确保页面完全活跃后再触发加载:

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) {
    // 路由动画完成后再执行音频加载
    audioHandler.setMediaItem(mediaItem);
    audioHandler.play();
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:45:08