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

Android TV设备Flutter just_audio插件dispose方法无实现崩溃求助

解决方案

1. 修复异步Dispose的异常捕获问题

你的dispose方法是同步的,但just_audio的dispose()是异步Future,直接调用不使用await的话,异步操作抛出的异常不会被外层的try/catch捕获,这就是Crashlytics能抓到未处理异常的核心原因。

修改dispose方法为异步,并await所有异步操作:

@override
Future<void> dispose() async {
  try {
    _timer?.cancel();
    WidgetsBinding.instance.removeObserver(this);
    _controller.dispose();
    await WakelockPlus.disable(); // 部分插件方法为异步,统一await避免潜在问题
    if (_soundPlayer != null) {
      await _soundPlayer.dispose();
    }
    if (_musicPlayer != null) {
      await _musicPlayer.dispose();
    }
  } catch (ex, st) {
    FirebaseCrashlytics.instance.recordError(ex, st, reason: 'workoutDispose');
  }
  super.dispose();
}

2. 针对MissingPluginException的防护

这个异常通常出现在Android TV/Chromecast设备上,原因是Flutter与原生的通道连接已失效(比如进程被后台回收、插件实例意外释放),此时调用dispose会找不到原生实现。

可以封装一个安全的播放器dispose方法,单独捕获该异常并忽略(因为此时原生资源已经不存在,无需重复释放):

// 封装安全的播放器释放方法
Future<void> _safeDisposePlayer(AudioPlayer? player) async {
  if (player == null) return;
  try {
    await player.dispose();
  } on MissingPluginException {
    // 忽略通道不存在的异常,记录日志即可
    FirebaseCrashlytics.instance.log('Ignored MissingPluginException during player dispose');
  } catch (ex, st) {
    FirebaseCrashlytics.instance.recordError(ex, st, reason: 'safePlayerDispose');
  }
}

// 在dispose中调用封装方法
@override
Future<void> dispose() async {
  try {
    _timer?.cancel();
    WidgetsBinding.instance.removeObserver(this);
    _controller.dispose();
    await WakelockPlus.disable();
    await _safeDisposePlayer(_soundPlayer);
    await _safeDisposePlayer(_musicPlayer);
  } catch (ex, st) {
    FirebaseCrashlytics.instance.recordError(ex, st, reason: 'workoutDispose');
  }
  super.dispose();
}

3. 适配Android TV的生命周期防护

Android TV的生命周期管理与手机存在差异,建议在页面进入后台时先暂停播放器,避免系统回收资源导致后续dispose出错:

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (state == AppLifecycleState.paused) {
    _soundPlayer?.pause();
    _musicPlayer?.pause();
  }
}

关于_disposePlatform的说明

_disposePlatform是just_audio内部的方法,作用是通过MethodChannel调用原生端的代码来释放播放器的底层资源。当Flutter与原生的通道连接失效时,这个调用就会抛出MissingPluginException。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:17:48