Flutter使用sqflite插入数据触发Null check operator空值报错如何解决
错误根因
- 核心问题:你在
main()函数内定义的database是局部变量,全局作用域下的database没有被赋值,调用insertTodo时访问的是未初始化的全局空变量,db!.insert的空断言操作直接触发崩溃。 - 潜在问题:sqflite本身不支持
DateTime、TimeOfDay类型的字段存储,就算修复数据库实例问题,后续插入也会抛出类型不支持异常。
修复步骤
- 调整
database变量作用域,改为全局变量并正确初始化,同时修正建表语句的字段类型:
// 在main函数外定义全局database实例 late final Future<Database> database; void main() async{ WidgetsFlutterBinding.ensureInitialized(); // 给全局database赋值 database = openDatabase( join(await getDatabasesPath(),'todo.db'), onCreate: (db,version){ // 调整字段类型为sqflite支持的类型,同时给id加主键自增属性 return db.execute('Create table todos(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, dateTime TEXT, timeOfDay TEXT)'); }, version: 1, ); runApp(MyApp()); }
- 调整
Todo类的序列化、反序列化逻辑,适配数据库存储格式:
class Todo{ final int id; final String title; final DateTime? dateTime; final TimeOfDay? timeOfDay; Todo(this.id, this.title, this.dateTime, this.timeOfDay,); Map<String,Object?> toMap(){ return{ 'id': id, 'title': title, // DateTime转成ISO标准字符串存储 'dateTime': dateTime?.toIso8601String(), // TimeOfDay转成"时:分"格式字符串存储 'timeOfDay': timeOfDay != null ? '${timeOfDay!.hour}:${timeOfDay!.minute}' : null, }; } // 新增fromMap方法,查询数据时可直接转成Todo对象 static Todo fromMap(Map<String, dynamic> map) { return Todo( map['id'] as int, map['title'] as String, map['dateTime'] != null ? DateTime.parse(map['dateTime'] as String) : null, map['timeOfDay'] != null ? TimeOfDay( hour: int.parse((map['timeOfDay'] as String).split(':')[0]), minute: int.parse((map['timeOfDay'] as String).split(':')[1]), ) : null, ); } @override String toString(){ return 'Todo{id: $id, title: $title, dateTime:$dateTime, timeOfDay:$timeOfDay}'; } }
- 修正
insertTodo方法,等待数据库初始化完成再执行插入操作:
Future<void> insertTodo(Todo todo)async{ // 加await拿到初始化完成的数据库实例 final db = await database; await db.insert('todos', todo.toMap(), conflictAlgorithm: ConflictAlgorithm.replace); }
- 可选优化:点击保存前增加非空校验,避免用户未选日期时间导致的空异常:
TextButton( onPressed: ()async{ if(selectedDate == null || selectedTime == null) { // 可自定义提示告知用户补全信息 return; } await insertTodo(Todo(0, 'num1', selectedDate , selectedTime)); }, child: const Text('保存') )
内容的提问来源于stack exchange,提问作者BatoulAlani
相关产品推荐
相关产品推荐

