Flutter Provider报错:Bad state: 读取创建时抛异常的Provider
解决Provider创建时抛出的"Bad state: Tried to read a provider that threw during the creation of its value"错误
问题场景
跟随教程开发音乐播放器,完成视频8:56左右的实现步骤后,运行代码抛出上述错误。
相关代码
main.dart
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:secondlife_mobile/model.dart'; void main() { runApp( MaterialApp( debugShowCheckedModeBanner: false, home: ChangeNotifierProvider( create: (context) => PlayerModel(), child: const PlayerApp()), ), ); } class PlayerApp extends StatefulWidget { const PlayerApp({super.key}); @override State<PlayerApp> createState() => _PlayerAppState(); } class _PlayerAppState extends State<PlayerApp> with TickerProviderStateMixin { AnimationController? _controller; Animation? _waveAnim; Animation? _waveConstAmpAnim; late PlayerModel model; @override void initState() { super.initState(); _controller = AnimationController(vsync: this, duration: const Duration(seconds: 20)) ..addListener(() => setState(() {})); _waveAnim = Tween<double>(begin: 1, end: 1).animate(_controller! /*null safe*/); _waveConstAmpAnim = Tween<double>(begin: 0, end: 1).animate(CurvedAnimation( curve: Curves.easeInSine, parent: _controller! /*null safe*/)); _controller!.forward(); //null safe 6:32 } @override Widget build(BuildContext context) { final height = MediaQuery.of(context).size.height; final width = MediaQuery.of(context).size.width; model = Provider.of<PlayerModel>(context); return Scaffold( body: Stack( children: <Widget>[ Positioned( height: height, width: width, child: Material( elevation: 16, color: const Color(0xFFd6dde5), //Background Color borderRadius: BorderRadius.circular(20), child: Padding( padding: const EdgeInsets.symmetric( horizontal: 30.0, ), child: Column( children: <Widget>[ const SizedBox( height: 90, ), const Text( 'Music title', ), const SizedBox( height: 15, ), const Text( 'Music artist', ), const SizedBox( height: 75, ), buildRecordPlayer(), const SizedBox( height: 60, ), Row( children: const <Widget>[ Text('time'), SizedBox( width: 8, ), /*buildWave(width),*/ SizedBox( width: 8, ), Text('end'), ], ) ], ), ), ), ) ], ), ); } Widget buildRecordPlayer() { return Container( height: 270, width: 270, alignment: Alignment.center, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/vinyl.png'), fit: BoxFit.fitHeight, colorFilter: ColorFilter.mode( Colors.blue, BlendMode.color, ), ), shape: BoxShape.circle, ), child: ClipOval( child: Image.asset( 'assets/images/SL.png', height: 165, width: 165, fit: BoxFit.fill, ), ), ); } }
model.dart
import 'dart:math'; import 'package:flutter/material.dart'; import 'musicdata.dart'; class PlayerModel extends ChangeNotifier { List<Music> musicList = []; int _currentTrack = 0; PlayerModel() { for (int i = 0; i < Data.nameList.length; i++) { musicList .add(Music(artistName: Data.artistList[i], name: Data.nameList[i])); } musicList.removeWhere( (musicItem) => musicItem.name == null || musicItem.artistName == null, ); for (var musicItem in musicList) { musicItem.duration = Duration( minutes: Random().nextInt(5).clamp(1, 5), seconds: Random().nextInt(59), ); } for (var music in musicList) { print(music.name); } } int get currentTrack => _currentTrack; set currentTrack(int currentTrack) { _currentTrack = currentTrack; notifyListeners(); } resetList() { for (var music in musicList) { music.isPlaying = false; } } } class Music { String? name; String? artistName; Duration? duration; bool? isPlaying = false; Music({this.duration, this.artistName, this.isPlaying, this.name}); }
报错信息
- 无调试运行时界面:

- 调试时错误提示:

- 调试控制台日志:


问题排查与解决
从调试控制台的错误栈可以看出,异常发生在PlayerModel的构造函数中,根源是**musicdata.dart中的Data类未正确定义,或者其中的nameList、artistList静态列表为空/未初始化**,导致访问Data.nameList.length时抛出空指针相关异常,进而导致Provider创建实例失败。
解决步骤
- 创建或完善
musicdata.dart文件,定义包含有效静态列表的Data类:
class Data { // 示例歌曲名列表,可根据需求修改 static List<String> nameList = [ "City Lights", "Ocean Waves", "Mountain Echo" ]; // 对应歌曲的歌手列表,需保证与nameList长度一致 static List<String> artistList = [ "Electro Band", "Acoustic Duo", "Rock Collective" ]; }
- 确保
nameList和artistList长度相同,避免循环时出现索引越界问题。 - 重新运行项目,此时
PlayerModel可以正常初始化,Provider的创建错误会被修复。
额外优化(可选)
在PlayerModel构造函数中添加校验逻辑,增强代码健壮性:
PlayerModel() { // 先校验列表有效性 if (Data.nameList.isEmpty || Data.artistList.isEmpty || Data.nameList.length != Data.artistList.length) { throw Exception("歌曲列表或歌手列表为空,或两者长度不匹配"); } // 原有初始化逻辑 for (int i = 0; i < Data.nameList.length; i++) { musicList.add(Music(artistName: Data.artistList[i], name: Data.nameList[i])); } // ...其他代码 }
内容的提问来源于stack exchange,提问作者loupdaniel
相关产品推荐
相关产品推荐

