Flutter中调用SQLite的insert方法出现NoSuchMethodError空指针错误求助
解决Flutter SQLite中"The method 'insert' was called on null"错误
这个错误我之前开发Flutter本地存储功能时也碰到过,核心问题出在数据库实例的管理和几个小细节上,咱们拆解来看:
错误原因分析
- 多实例问题:你每次调用
Database_()都会创建一个全新的类实例。main函数里你初始化了一个Database_实例并调用了openDBFunction(),但这个实例用完就被丢弃了;而在addEntry方法里你又new了一个全新的Database_实例,这个新实例的database变量根本没执行初始化,自然就是null,调用insert方法时就会报错。 - 表名不匹配:你的
insertEntry方法里写的是插入到'entry'表,但创建表的SQL语句里是entries,这个小问题后续也会导致数据插入失败。 - 文本获取错误:你用
_controller.toString()获取的是TextField控制器对象的字符串表示,不是用户输入的文本内容;而且日期你传的是字符串"DateTime.now().toString()",这只是个字符串,不是实际的当前时间。
解决方案
1. 将Database_改为单例模式(核心修复)
确保整个App中只有一个数据库实例,初始化一次后所有地方共享这个实例:
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqlite_api.dart'; import 'Entry.dart'; import 'package:path/path.dart'; class Database_ { // 单例核心:私有构造函数+静态实例 static final Database_ _instance = Database_._internal(); factory Database_() => _instance; Database_._internal(); Future<Database>? database; void openDBFunction() async { var databasesPath = await getDatabasesPath(); String path = join(databasesPath, 'Journal Entries.db'); database = openDatabase(path, version: 1, onCreate: (Database db, int version) async { await db.execute( "CREATE TABLE entries( _entry TEXT, _date TEXT)" ); }); } Future<void> insertEntry(Entry entry) async { final Database db = await database!; await db.insert( 'entries', // 修正表名,和创建表时一致 entry.toMap(), conflictAlgorithm: ConflictAlgorithm.replace, ); } Future<List<Entry>> entries() async { final Database db = await database!; final List<Map<String, dynamic>> maps = await db.query('entries'); return List.generate(maps.length, (i) { return Entry( maps[i]["_entry"], maps[i]["_date"], ); }); } }
2. 修正页面中的调用逻辑
- main.dart:保持原来的初始化逻辑即可,现在调用的是单例实例
main()async { WidgetsFlutterBinding.ensureInitialized(); Database_().openDBFunction(); runApp(MyApp()); }
- MainPage.dart:修正文本获取和日期传递的错误,同时确保调用的是单例实例:
// 修正TextField的onPressed逻辑 suffixIcon: IconButton( onPressed: () { addEntry(_controller.text, DateTime.now().toString()); _controller.clear(); // 可选:发送后清空输入框,提升体验 }, icon: Icon(Icons.send_outlined), ), // 修正addEntry方法 void addEntry(String entry_, String date_)async { final entry = Entry(entry_, date_); Database_().insertEntry(entry); // 现在调用的是已初始化的单例实例 }
这样修改后,数据库实例会被正确初始化并全局共享,表名匹配,文本和日期也能正确传递,那个null错误就会消失啦。
内容的提问来源于stack exchange,提问作者Nush
相关产品推荐
相关产品推荐

