Flutter:使用just_audio播放音频,杀死应用后仍后台播放如何解决
解决 just_audio 后台杀死应用后音乐继续播放的问题
核心思路
Flutter 的 AppLifecycleState.detached 在应用被主动杀死时触发不可靠,尤其是 Android 任务管理器杀进程场景。需要依赖原生平台的生命周期回调通知 Flutter 安全停止播放并释放资源,避免内存泄漏。
1. Android 端:监听任务移除事件
在 MainActivity 中重写 onTaskRemoved 方法(应用从最近任务列表被移除时触发),通过 MethodChannel 通知 Flutter 停止播放,并终止后台音频服务。
class MainActivity : FlutterActivity() { private val CHANNEL = "com.your.package.audio_control" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "stopAudio") { result.success(null) } } } override fun onTaskRemoved(rootIntent: Intent?) { super.onTaskRemoved(rootIntent) flutterEngine?.let { engine -> val channel = MethodChannel(engine.dartExecutor.binaryMessenger, CHANNEL) channel.invokeMethod("stopAudio", null) // 终止后台音频服务,确保通知栏移除 stopService(Intent(this, YourBackgroundAudioService::class.java)) } } }
2. iOS 端:监听应用终止事件
在 AppDelegate 中重写 applicationWillTerminate 方法(应用即将终止时触发),通过 MethodChannel 通知 Flutter 停止播放。
import UIKit import Flutter @UIApplicationMain class AppDelegate: FlutterAppDelegate { let CHANNEL = "com.your.package.audio_control" override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { guard let controller = window?.rootViewController as? FlutterViewController else { return super.application(application, didFinishLaunchingWithOptions: launchOptions) } let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { call, result in if call.method == "stopAudio" { result(nil) } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } override func applicationWillTerminate(_ application: UIApplication) { guard let controller = window?.rootViewController as? FlutterViewController else { return } let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger) channel.invokeMethod("stopAudio", arguments: nil) } }
3. Flutter 端:安全停止并释放播放器
通过 MethodChannel 接收原生指令,在 UI 未销毁的安全时机停止播放、释放播放器资源,避免内存泄漏。
import 'package:flutter/services.dart'; import 'package:just_audio/just_audio.dart'; import 'package:just_audio_background/just_audio_background.dart'; class AudioPlayerManager { static const MethodChannel _audioControlChannel = MethodChannel('com.your.package.audio_control'); AudioPlayer? _player; Future<void> initPlayer() async { _player = AudioPlayer(); // 初始化后台播放配置(示例) await _player!.setAudioSource( AudioSource.uri(Uri.parse('your_audio_url')), metadata: const MediaMetadata(title: "示例音频"), ); // 监听原生传来的停止指令 _audioControlChannel.setMethodCallHandler((call) async { if (call.method == 'stopAudio') { await _stopAndDisposePlayer(); } }); } Future<void> _stopAndDisposePlayer() async { if (_player != null) { await _player!.stop(); await _player!.dispose(); _player = null; // 确保通知栏移除,just_audio_background 通常会自动处理,若未生效可手动触发 await AudioService.stop(); } } }
关键注意事项
- 不要在
AppLifecycleState.detached中操作播放器:此时 Flutter UI 已销毁,资源引用失效,易引发内存泄漏。 - 确保
just_audio_background配置正确:播放器停止并释放后,通知栏应自动消失,若未消失,可调用AudioService.stop()强制终止后台服务。
内容的提问来源于stack exchange,提问作者Md Usama
相关产品推荐
相关产品推荐

