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

Flutter使用sqflite插入数据触发Null check operator空值报错如何解决

错误根因

  • 核心问题:你在main()函数内定义的database是局部变量,全局作用域下的database没有被赋值,调用insertTodo时访问的是未初始化的全局空变量,db!.insert的空断言操作直接触发崩溃。
  • 潜在问题:sqflite本身不支持DateTime、TimeOfDay类型的字段存储,就算修复数据库实例问题,后续插入也会抛出类型不支持异常。

修复步骤

  1. 调整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());
} 
  1. 调整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}';
  }
}
  1. 修正insertTodo方法,等待数据库初始化完成再执行插入操作:
Future<void> insertTodo(Todo todo)async{
  // 加await拿到初始化完成的数据库实例
  final db = await database;
  await db.insert('todos', todo.toMap(), conflictAlgorithm: ConflictAlgorithm.replace);
}
  1. 可选优化:点击保存前增加非空校验,避免用户未选日期时间导致的空异常:
TextButton(
  onPressed: ()async{
    if(selectedDate == null || selectedTime == null) {
      // 可自定义提示告知用户补全信息
      return;
    }
    await insertTodo(Todo(0, 'num1', selectedDate , selectedTime));
  },
  child: const Text('保存')
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:27:00