Flutter中assets目录chinook.db数据库无法正常复制至应用目录问题
Flutter 从Assets复制SQLite数据库后无数据仅显示'en_US'的解决方法
可能的原因及排查步骤
Assets中的数据库文件本身异常
- 先在本地用SQLite工具(比如DB Browser for SQLite)打开
assets/chinook.db,确认里面有完整的数据表和内容,而非仅含'en_US'的空文件。 - 若本地文件正常,执行
flutter clean清除缓存,再运行flutter pub get重新打包assets,避免旧的无效文件被缓存。
- 先在本地用SQLite工具(比如DB Browser for SQLite)打开
Pubspec.yaml配置错误
- 确保assets配置缩进正确,必须在
flutter:节点下,格式如下:flutter: assets: - assets/chinook.db - 配置完成后重新执行
flutter pub get,确保assets被正确打包。
- 确保assets配置缩进正确,必须在
数据库复制过程不完整
- 原代码缺少父目录创建校验,且未确保数据完全刷入磁盘,修改后的复制逻辑如下:
修改后的完整代码
Future<void> _openDatabase() async { try { final databasesPath = await getDatabasesPath(); final path = join(databasesPath, 'chinook.db'); final dbFile = File(path); // 检查现有文件是否为无效空文件(大小过小),是则删除重拷 if (await dbFile.exists()) { final fileSize = await dbFile.length(); // Chinook.db正常大小远大于1KB,可根据实际文件大小调整阈值 if (fileSize < 1024) { await dbFile.delete(); } } final exists = await databaseExists(path); if (!exists) { // 确保数据库目录存在 await Directory(databasesPath).create(recursive: true); // 从Assets读取数据库文件 final ByteData data = await rootBundle.load('assets/chinook.db'); final List<int> bytes = data.buffer.asUint8List( data.offsetInBytes, data.lengthInBytes, ); // 写入文件并强制刷入磁盘,避免写入不完整 await dbFile.writeAsBytes(bytes, flush: true); // 校验写入后的文件大小是否和原文件一致 final writtenSize = await dbFile.length(); if (writtenSize != bytes.length) { throw Exception('数据库复制不完整:原大小${bytes.length}字节,写入后$writtenSize字节'); } } // 打开数据库时指定与原文件匹配的版本号 _database = await openDatabase( path, version: 1, // 请确认chinook.db的实际版本号,可通过SQLite工具查看 onConfigure: (db) async { // 可选:开启外键支持,避免关联数据异常 await db.execute('PRAGMA foreign_keys = ON'); }, ); setState(() { _isDatabaseConnected = true; }); print('数据库连接成功,文件大小:${await dbFile.length()}字节'); } catch (e) { print('数据库操作错误:$e'); } }
额外验证步骤
- 安装应用后,用
adb pull命令把手机里的数据库文件拉到本地检查:
用SQLite工具打开adb pull /data/data/com.example.your_app_name/databases/chinook.db ./local_chinook.dblocal_chinook.db,确认数据是否完整。
内容的提问来源于stack exchange,提问作者Alexander Urquico
相关产品推荐
相关产品推荐

