Flutter空安全下sqflite的database变量初始化报LateInitializationError错误
问题根因
createDatabase()是异步方法,initState不支持async/await,直接调用不会阻塞等待数据库初始化完成,页面渲染后如果用户提前操作触发数据库读写,database还没完成赋值就会抛出LateInitializationErroropenDatabase的onOpen回调参数名拼写错误,且回调内部错误调用了还未完成赋值的全局database变量,会直接触发初始化报错- 插入数据的SQL语句中错误传入了
$timeController控件对象,而非传入时间参数值,会导致存储异常
解决方案
步骤1:调整变量声明,增加加载状态控制
替换原late Database database;声明,避免未初始化访问:
// 替换原有database相关声明 Database? database; bool isDbLoading = true;
步骤2:修复createDatabase方法逻辑
修正参数错误,初始化完成后更新加载状态:
Future<void> createDatabase() async { database = await openDatabase( 'todo.db', version: 1, onCreate: (db, version) { print('database created'); db.execute( 'CREATE TABLE tasks(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, date TEXT, time TEXT, status TEXT)' ).then( (value) { print('table created'); } ).catchError( (error){ print('error creating table ${error.toString()}'); } ); }, // 用回调传入的db实例操作,不要调用全局未赋值的database onOpen: (db) async { print('database opened'); await getData(db).then((value) { setState(() { tasks = value; isDbLoading = false; }); print(tasks); }); } ); }
步骤3:页面增加加载状态防护
修改build方法的body逻辑,数据库未初始化完成前显示加载占位,禁止用户操作:
body: isDbLoading ? const Center(child: CircularProgressIndicator()) : screens[currentIndex],
步骤4:修复悬浮按钮点击逻辑与SQL语句错误
- 点击事件增加初始化状态判断,避免加载中触发数据库操作
- 修正插入语句的参数引用错误
// 悬浮按钮onPressed开头增加判断 onPressed: () { if (isDbLoading) return; // 原有逻辑不变 // ... // 修复插入SQL的参数错误 'INSERT INTO tasks (title, date, time, status) VALUES ("$title", "$date", "$time", "new")' }
内容的提问来源于stack exchange,提问作者Abdallah Rashed
相关产品推荐
相关产品推荐

