Flutter切换页面时出现Sqflite database_closed数据库关闭报错求助
问题原因排查
- 核心原因:你的
DbHelper中_db是全局静态单例实例,若你在任意页面的dispose等生命周期中主动调用了Database.close()方法,单例就会被标记为关闭状态,后续其他页面再复用这个已经关闭的实例就会抛出database_closed异常。 - 附加逻辑问题:你当前
initDb方法中每次初始化都会删除已有数据库、重写assets中的预置库,若单例被销毁重建,会导致所有用户产生的运行时数据丢失,同时极端情况下删库重写的过程中触发读写也会报错。 - 小概率场景:你在页面触发数据库异步查询后,还未等待返回就销毁了页面上下文,异步回调中持有了已经被回收的数据库实例引用。
修复方案
1. 移除所有主动关闭数据库的代码
全局检索项目中所有调用close()方法操作数据库实例的代码,全部删除。正常应用生命周期内不需要主动关闭sqflite数据库,应用退出时系统会自动回收相关资源。
2. 修正DbHelper的初始化逻辑
删除每次初始化删库的逻辑,增加本地数据库是否存在的判断,只有本地数据库不存在的时候才拷贝assets中的预置库,避免数据丢失,修改后的参考代码如下:
import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; import 'package:bankingapp/models/coin.dart'; import 'package:bankingapp/models/histories.dart'; import 'package:flutter/services.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; class DbHelper { static Database? _db; Future<Database> get db async { // 增加实例打开状态校验,被关闭后自动重新初始化 if (_db == null || !_db!.isOpen) { _db = await initDb(); } return _db!; } Future<Database> initDb() async { var dbFolder = await getDatabasesPath(); String path = join(dbFolder, 'app.db'); // 仅本地数据库不存在时拷贝预置库,删除原有的强制删库逻辑 bool dbExists = await databaseExists(path); if (!dbExists) { try { await Directory(dirname(path)).create(recursive: true); } catch (_) {} ByteData data = await rootBundle.load(join("assets/database", "bankingapp.db")); List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); await File(path).writeAsBytes(bytes, flush: true); } return await openDatabase(path); } Future<List<Histories>> getHistories() async { var dbClient = await db; var result = await dbClient.rawQuery("SELECT * FROM Histories"); return result.map((data) => Histories.fromMap(data)).toList(); } Future<List<Coins>> getCoins() async { var dbClient = await db; var result = await dbClient.rawQuery("SELECT * FROM Coins"); return result.map((data) => Coins.fromMap(data)).toList(); } }
3. 适配数据库版本迭代(可选)
如果后续需要更新预置的数据库、或者做表结构变更,可以在openDatabase方法中传入version参数和onUpgrade回调,处理版本升级逻辑,避免覆盖用户本地数据。
内容的提问来源于stack exchange,提问作者MaybeExpertDBA
相关产品推荐
相关产品推荐

