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

使用Just Audio Background包时遇'Null不是MediaItem子类型'错误

问题:Just Audio Background首次播放报错“type 'Null' is not a subtype of type 'MediaItem'”,多次重启后可正常播放

问题详情

使用Just Audio Background实现后台音乐播放时,每次启动应用后首次播放都会触发类型转换错误,但多次重启应用后音乐能正常播放。已通过OnAudioQuery成功获取设备本地音乐数据,添加Just Audio Background后出现此问题。

相关代码

获取音乐数据的fetchMusic方法

Future<void> fetchMusic() async {
  _audioQuery = OnAudioQuery();
  _musicList = await _audioQuery.querySongs(
    sortType: SongSortType.DATE_ADDED,
    orderType: OrderType.DESC_OR_GREATER,
    uriType: UriType.EXTERNAL,
    ignoreCase: true,
  );

  _artistList = await _audioQuery.queryArtists();

  notifyListeners();
}

音乐播放控制类MusicPlayerController

class MusicPlayerController extends ChangeNotifier {
  final player = AudioPlayer();
  var shuffledList;
  var numbersSet = <int>{};
  int _playingIndex = 0;

  final GetMusicProvider _musicProvider;
  late PlayerStateles _playerStateles;
  late BuildContext context;

  MusicPlayerController(this._musicProvider, this._playerStateles) {
    player.playerStateStream.listen((state) {
      if (state.processingState == ProcessingState.completed) {
        playOrPause(_playingIndex+1, 
        _musicProvider.musicList[_playingIndex+1].uri.toString());
      }
    });
  }

  Future<void> playOrPause(int index, String uri) async {
    log("1");
    if (index == _playingIndex) {
      if (player.playing){
        player.stop();
        icon(index);
      } else { 
        player.play();
        icon(index);
      }     
    } else {
      MediaItem? mediaItem;
      mediaItem = MediaItem(
        id: _musicProvider.musicList[index].id.toString(),
        title: _musicProvider.musicList[index].title,
      );

      player.setAudioSource(AudioSource.uri(
        Uri.parse(uri),
        tag: mediaItem,
      ));
      player.play();
      _playingIndex = index;
      _playerStateles.updateCurrentIndex(index);
      icon(index);
      _musicProvider.refreshPage();
    }
    notifyListeners(); 
  }

  Icon icon(int index) { 
    if (index == _playingIndex) { 
      return player.playing ? Icon(Icons.pause_circle) : 
        Icon(Icons.play_circle_outline_outlined) ;
    } else {
      return Icon(Icons.play_circle_outline_outlined);
    }
  }
}

完整错误栈

E/flutter (15426): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'MediaItem' in type cast
E/flutter (15426): #0   _PlayerAudioHandler._updateQueue.
(package:just_audio_background/just_audio_background.dart:597:51)
E/flutter (15426): #1      MappedListIterable.elementAt (dart:_internal/iterable.dart:425:31)
E/flutter (15426): #2      ListIterator.moveNext (dart:_internal/iterable.dart:354:26)
E/flutter (15426): #3      new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189:27)
E/flutter (15426): #4      new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
E/flutter (15426): #5      new List.of (dart:core-patch/array_patch.dart:39:18)
E/flutter (15426): #6      ListIterable.toList (dart:_internal/iterable.dart:224:7)
E/flutter (15426): #7      _PlayerAudioHandler._updateQueue (package:just_audio_background/just_audio_background.dart:597:65)
E/flutter (15426): #8      _PlayerAudioHandler.customLoad (package:just_audio_background/just_audio_background.dart:482:5)
E/flutter (15426): #9      _JustAudioPlayer.load (package:just_audio_background/just_audio_background.dart:237:27)
E/flutter (15426): #10     AudioPlayer._load (package:just_audio/just_audio.dart:850:12)

解决建议

  1. 校验音乐列表状态:错误根源是首次播放时_musicProvider.musicList未完成加载,导致取到Null数据。在playOrPause中先校验数据有效性:
Future<void> playOrPause(int index, String uri) async {
  log("1");
  // 新增数据校验逻辑
  if (_musicProvider.musicList.isEmpty || index < 0 || index >= _musicProvider.musicList.length) {
    log("无效播放索引或音乐列表未加载");
    return;
  }
  // 原播放逻辑...
}
  1. 确保MediaItem非空:将MediaItem声明为非空类型,避免潜在的Null风险:
// 替换原MediaItem? mediaItem;
final mediaItem = MediaItem(
  id: _musicProvider.musicList[index].id.toString(),
  title: _musicProvider.musicList[index].title,
);
  1. 延迟播放触发时机:在UI层监听GetMusicProvider的状态,音乐列表加载完成前禁用播放按钮,避免用户过早触发播放操作。

  2. 检查Just Audio Background初始化:确保应用启动时已完成Just Audio Background的初始化,比如在main函数中执行:

void main() async {
  await JustAudioBackground.init(
    androidNotificationChannelId: 'your_music_channel',
    androidNotificationChannelName: '音乐播放',
    androidNotificationOngoing: true,
  );
  runApp(MyApp());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:03:20