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
相关产品推荐
相关产品推荐

