Flutter just_audio安卓后台运行约10分钟后异常终止求助
问题描述
Flutter应用使用just_audio实现音频循环播放功能(10秒音频+1秒静音循环),iOS运行正常,但Android后台运行约10分钟后应用被终止,VSCode提示Lost connection to device.。
已完成的配置:
- AndroidManifest中添加权限:
<uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> - 核心播放代码:
AudioPlayer audioPlayer = AudioPlayer(); final playlist = ConcatenatingAudioSource( useLazyPreparation: true, shuffleOrder: DefaultShuffleOrder(), children: [ AudioSource.uri(Uri.file("$path/$fileName")), AudioSource.uri(Uri.parse("${Constants.soundsLocation}silence.mp3")), ], ); await audioPlayer.setAudioSource(playlist, initialPosition: Duration.zero); audioPlayer.setLoopMode(LoopMode.all); audioPlayer.setVolume(1); audioPlayer.setSpeed(1); audioPlayer.play();
排查情况:
- 排除Doze Mode影响,执行
adb shell dumpsys deviceidle force-idle强制触发后问题仍存在 - 调试模式无异常捕获,Logcat崩溃前日志:
I/ActivityManager: Killing 25231:com.appname.app/u0a158 (adj 700): excessive cpu 220780 during 300021 dur=548815 limit=25 - 模拟器和真机均出现该问题
解决方案
1. 优化音频资源加载与复用
- 将
AudioPlayer和ConcatenatingAudioSource设为全局单例,避免每次循环或页面重建时重复创建实例,减少资源重复加载带来的CPU消耗。 - 移除
shuffleOrder: DefaultShuffleOrder(),当前场景不需要随机播放,该配置会额外消耗CPU维护随机序列。
修改后的初始化代码示例:
// 全局单例播放器,避免重复创建 final AudioPlayer audioPlayer = AudioPlayer(); ConcatenatingAudioSource? _playlist; Future<void> initPlayer(String path, String fileName) async { if (_playlist != null) return; // 避免重复初始化 _playlist = ConcatenatingAudioSource( useLazyPreparation: true, children: [ AudioSource.uri(Uri.file("$path/$fileName")), AudioSource.uri(Uri.parse("${Constants.soundsLocation}silence.mp3")), ], ); await audioPlayer.setAudioSource(_playlist!, initialPosition: Duration.zero); audioPlayer.setLoopMode(LoopMode.all); audioPlayer.setVolume(1); audioPlayer.setSpeed(1); }
2. 启用前台服务维持后台播放
Android后台长时间播放音频必须使用前台服务,否则系统会判定应用为低优先级进程,结合CPU过高的情况更容易被杀死。可以配合audio_service插件实现:
- 在AndroidManifest中添加前台服务配置:
<service android:name="com.ryanheise.audioservice.AudioService" android:foregroundServiceType="mediaPlayback" android:exported="true"> <intent-filter> <action android:name="android.media.browse.MediaBrowserService" /> </intent-filter> </service> - 使用
audio_service封装播放逻辑,后台播放时系统会显示媒体通知,提升进程优先级,避免被随意终止。
3. 排查静音音频文件问题
如果静音音频存在编码异常、时长不符等问题,会导致播放器反复处理异常,增加CPU消耗:
- 替换静音音频为编码规范、时长准确的版本,或直接用代码生成静音流(避免本地文件加载的额外开销)。
- 确保静音音频的采样率、编码格式与主音频一致,减少播放器切换时的解码配置开销。
4. 削减不必要的CPU消耗
- 关闭非必要的播放器监听事件(如频繁的
onPositionChanged监听),仅保留核心业务所需的回调。 - 排查应用后台运行时的其他高CPU任务(如定时器、重复网络请求),暂停或优化这类逻辑。
5. 确认唤醒锁状态
检查播放器是否正确持有唤醒锁,避免因设备休眠导致的异常:
print(audioPlayer.androidAudioSession.isWakeLockEnabled);
若未启用,可通过just_audio的配置开启:
await audioPlayer.setAndroidAudioSessionId(/* 对应会话ID */);
内容的提问来源于stack exchange,提问作者luminous
相关产品推荐
相关产品推荐

