Flutter WebView应用退至后台时停止音频播放的问题求助
解决Flutter WebView后台时网页音频持续播放的问题
我刚好碰到过一模一样的问题!这是因为App退到后台后,WebView的JavaScript环境并没有停止运行,所以网页里的音频会自顾自继续播放。咱们可以通过监听Flutter的App生命周期,主动通知WebView执行JS代码来暂停音频,具体实现步骤如下:
步骤1:添加App生命周期监听
在你的WebView页面的State类中,混入WidgetsBindingObserver,并在页面初始化和销毁时完成监听的注册与移除:
class _YourWebViewPageState extends State<YourWebViewPage> with WidgetsBindingObserver { late WebViewController _webViewController; bool _isLoading = true; @override void initState() { super.initState(); // 注册生命周期监听 WidgetsBinding.instance.addObserver(this); } @override void dispose() { // 移除监听,避免内存泄漏 WidgetsBinding.instance.removeObserver(this); super.dispose(); } // ... 你的其他现有代码 }
步骤2:监听状态变化并控制音频
重写didChangeAppLifecycleState方法,当检测到App进入后台(paused状态)时,调用WebView的JS执行能力暂停音频:
@override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); // 当App退到后台时执行暂停逻辑 if (state == AppLifecycleState.paused) { _webViewController.evaluateJavascript(''' var aid = document.getElementById('audio01'); if (!aid.paused) { aid.pause(); // 同步更新网页上的播放按钮状态,和你的原有JS逻辑保持一致 $('.music').css("background-image", "url(images/music_s.png)"); } '''); } // 可选:如果需要App回到前台时自动恢复播放,取消下面的注释 // else if (state == AppLifecycleState.resumed) { // _webViewController.evaluateJavascript(''' // var aid = document.getElementById('audio01'); // if (aid.paused) { // aid.play(); // $('.music').css("background-image", "url(images/music.png)"); // } // '''); // } }
步骤3:保存WebViewController引用
修改你的WebView代码,通过onWebViewCreated回调拿到控制器实例,这样后续才能调用JS执行方法:
WebView( initialUrl: widget.url, javascriptMode: JavascriptMode.unrestricted, // 保存控制器引用 onWebViewCreated: (controller) { _webViewController = controller; }, onPageFinished: (finish) { setState(() { _isLoading = false; }); }, ),
额外优化:网页端封装统一控制函数
为了让Flutter端的调用更简洁,你可以在网页的JS代码里封装一个全局函数:
// 网页端新增全局暂停函数 function pauseAudio() { var aid = document.getElementById('audio01'); if (!aid.paused) { aid.pause(); $('.music').css("background-image", "url(images/music_s.png)"); } } // 你的原有播放控制逻辑保持不变 var aid = document.getElementById('audio01'); $('.music').bind('touchstart click', function(e) { e.preventDefault(); if (aid.paused) { aid.play(); $(this).css("background-image", "url(images/music.png)"); } else { aid.pause(); $(this).css("background-image", "url(images/music_s.png)"); } });
之后Flutter端的调用就可以简化成:
_webViewController.evaluateJavascript('pauseAudio();');
这样修改后,用户按下Home键把App退到后台时,WebView就会自动执行暂停音频的逻辑,完美解决后台音频持续播放的问题~
内容的提问来源于stack exchange,提问作者pavanvikas ak
相关产品推荐
相关产品推荐

