Flutter Sqflite真机报错:null check operator used on a null value
解决Flutter sqflite真机上"null check operator used on a null value"错误
错误原因
- 调用
DBHelper.query()或insert()时,数据库初始化方法initDb()未执行完成,静态变量_db仍为null,触发null check崩溃。 - 真机上直接用
+拼接数据库路径可能导致格式错误,导致openDatabase执行失败,_db未被正确赋值。
解决方案
1. 确保数据库操作前完成初始化
在DBHelper的所有数据库操作方法开头,强制先执行初始化,保证_db非空:
修改后的db_helper.dart关键代码:
static Future<int> insert(Task? task) async { await initDb(); // 新增:先完成数据库初始化 print("Insert Function Called"); return await _db?.insert(_tableName, task!.toJson()) ?? 1; } static Future<List<Map<String, dynamic>>> query() async { await initDb(); // 新增:先完成数据库初始化 print("Query Function Called"); // 可选:增加null判断,避免崩溃 if (_db == null) { throw Exception("数据库初始化失败"); } return await _db!.query(_tableName); }
2. 修复数据库路径拼接问题
真机路径格式要求更严格,改用path包的join方法拼接路径,确保跨平台兼容:
- 先导入path包:
import 'package:path/path.dart' as path;
- 修改
initDb里的路径代码:
try { // 替换原路径拼接方式 String _path = path.join(await getDatabasesPath(), 'tasks.db'); _db = await openDatabase(_path, version: _version, onCreate: (db, version) { print("Creating A New One"); return db.execute("CREATE TABLE $_tableName(" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "title STRING, note TEXT, date STRING, " "startTime STRING, endTime STRING, " "remind INTEGER, repeat STRING, " "color INTEGER, " "isCompleted INTEGER)"); }); } catch (e) { print(e); }
3. 提前初始化数据库(可选)
在应用启动时提前完成数据库初始化,避免后续操作重复执行:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await DBHelper.initDb(); // 应用启动时提前初始化 runApp(MyApp()); }
修改完成后重新打包到真机测试,即可解决点击创建任务按钮后的null check错误。
内容的提问来源于stack exchange,提问作者Chaitya Vohera
相关产品推荐
相关产品推荐

