使用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)
解决建议
- 校验音乐列表状态:错误根源是首次播放时
_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; } // 原播放逻辑... }
- 确保MediaItem非空:将MediaItem声明为非空类型,避免潜在的Null风险:
// 替换原MediaItem? mediaItem; final mediaItem = MediaItem( id: _musicProvider.musicList[index].id.toString(), title: _musicProvider.musicList[index].title, );
延迟播放触发时机:在UI层监听
GetMusicProvider的状态,音乐列表加载完成前禁用播放按钮,避免用户过早触发播放操作。检查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
相关产品推荐
相关产品推荐

