如何在 Flutter 中使用预填充的 sqlite 数据库我的应用程序
Posted
技术标签:
【中文标题】如何在 Flutter 中使用预填充的 sqlite 数据库我的应用程序【英文标题】:How to use a pre-populated sqlite database my App in Flutter 【发布时间】:2018-06-22 12:08:13 【问题描述】:正如标题中的问题所说。
我的数据库文件可能非常大,所以我不想不必要地复制它,我当然也不想在原地构建它。
如果db文件是flutter资产,sqlite有办法直接访问吗?
我看到有人建议我应该将资产的原始数据复制到一个文件中,然后再访问它,但这是对存储的浪费。或者我可以删除资产吗?
有没有一种简单的方法将数据库部署为资产以外的东西,即作为原始文件?
【问题讨论】:
我认为将您的资产复制到文件存储并使用它是您最好/唯一的选择。 仍在研究颤振,但已经解决了 ios 和 android 的这个问题,也许这很有用:iOS 包允许以只读模式打开并直接使用包含的 SQLite 数据库。 Android 包需要先复制,因为 db 文件是从压缩包中流式传输的。所以这取决于 Flutter 如何映射到原生包格式。您也许可以对我的本机应用程序执行我所做的操作,并在 iOS 上以只读方式使用它,并在对任何预先存在的数据库进行版本检查后复制到 Android 上(请参阅github.com/jgilfelt/android-sqlite-asset-helper)。请注意,SQLite ATTACH 在这两种情况下都适用 - 方便! 【参考方案1】:iOS(我认为是 Android?)将要求您首先将文件复制到应用程序的工作目录中。这是标准做法,它是在受保护文件系统中工作的一部分。如果以某种方式在您的应用程序包(认为这是原始的“主”)和应用程序文档文件夹(“工作副本”)中都有副本是一个交易杀手,我想您也可以在初始应用程序启动时从服务器下载它,但是……时间就是金钱。
不过,这确实没什么大不了的。为此,请确保通过您的 pubspec.yaml 文件将文件包含在应用程序包中:
flutter:
assets:
- assets/stored_data.db
然后,在打开数据库之前,将其从 app bundle 复制到您的文档目录:
编辑:以下显然无法复制大文件;如果您遇到此类问题,请参阅下面的 iKK 评论,因为看起来他找到了本机解决方案。但是,对于较小的文件,这应该可以正常工作。
// Create a new file within your document directory (Probably want to check whether it already exists first...)
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "working_data.db");
ByteData data = await rootBundle.load(join("assets", "stored_data.db"));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes);
现在您的应用程序文档目录中已经有了数据库,您应该可以从 path.
打开它,您可以简单地:
Database db = await openDatabase(path); // Opens SQL database, working_data.db
没有理由(或能力)从应用程序包中删除原始副本(这会改变原始二进制文件 - huge nono)。最终,操作系统本身可能最终会将这些垃圾卸载到云服务器或其他内存管理服务,但这由平台决定。
【讨论】:
不错 - 但不幸的是rootBundle.load(join("assets", "mydb.db"));
不适用于大型 db 文件(...即我的大于 665 MB)。除了为每个世界创建原生插件之外,还有其他选择吗?
最终使用 Flutter-plugin 解决了这个问题,该插件可以本地执行大文件复制(分别在 iOS 和 Android 中)-see my solution here 或如上所述的@mm2001,this 也可能有帮助...
很高兴知道,@iKK。我自己没有遇到过大文件问题,但是您的解决方案看起来不错。我已经编辑了我的原始答案,以将其他人推荐给您的评论。谢谢!以上是关于如何在 Flutter 中使用预填充的 sqlite 数据库我的应用程序的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 2.1 中使用姓氏字段预填充“添加联系人”活动?