如何使用Flutter将数据保存到本地存储?

158
在Android中,如果我有想要在会话之间保留的信息,我知道可以使用SharedPreferences或创建一个SQLite数据库,甚至可以将文件写入设备并稍后读取它。
在Flutter中是否有一种只使用Flutter就能保存和恢复这样的数据的方法?还是我需要像服务示例中那样为Android和iOS编写特定于设备的代码?
10个回答

169

1
我编写了一个Flutter服务来访问SQLite,详情请见https://github.com/ripple182/FlutterSQLiteSample。 - ripple182
如果我使用Room,这是可能的吗?如果我使用Room会对iOS有什么影响吗? - MNFS
1
这似乎更适用于共享首选项:https://pub.dev/packages/shared_preferences - Yster
1
新的软件包 https://github.com/lesnitsky/flutter_localstorage - Pablo Díaz
1
在上面的选项中,推荐使用哪种存储方式来存储身份验证令牌(如访问令牌、ID 令牌等)? - Nickr
显示剩余2条评论

96

如果您处于想要保存稍后引用的小值的情况中,那么您应该使用shared_preferences将数据存储为键值对数据。

但是,如果您想存储大量数据,应该使用SQLITE。

不过,您始终可以使用离线可用的Firebase数据库。

既然我们正在谈论本地存储,您始终可以读取和写入磁盘上的文件。

其他解决方案:

1
如何决定何时使用 sqflite 或 firebase? - stuckedoverflow
1
sqflite 只在手机上存储数据。firebase 则会将数据同步到中央数据库,您可以在后端执行查询操作。firebase 还可以轻松实现设备之间的同步。 - Feu
请注意,Firebase的Firestore默认为10MB,最小值不得低于1MB,最大值为100MB。不建议纯离线访问。如果您计划仅将其用作本地存储选项,并且数据较大,则可能需要重新考虑。https://firebase.google.com/docs/reference/android/com/google/firebase/database/FirebaseDatabase#setPersistenceCacheSizeBytes(long) - astone26
1
这应该是首选答案,因为它简单地解释了在不同情况下应该去哪里查找。 - janpeterka

27

虽然回答比较晚,但我希望它能帮助任何以后来访问这里的人。

我将提供需要存储的类别以及它们各自最佳的方法...

  1. 共享首选项 当在存储简单值时使用,例如颜色主题、应用程序语言、上次滚动位置(在阅读应用程序中).. 这些是希望在应用程序重新启动时保持不变的简单设置.. 但您也可以使用此方法存储大的东西(列表、映射、图像),但那需要序列化和反序列化.. 如需了解更多信息,请单击此处
  2. 文件 当数据更多由你自己定义时,例如日志文件、图像文件,也许您想要导出 csv 文件时,这会非常有帮助。我听说这种类型的持久性可能会被存储清理程序清除一旦磁盘空间不足.. 我不确定因为我从未见过.. 但是这种方法也可以存储几乎任何东西,只需要序列化和反序列化的帮助..
  3. 保存到数据库 这对于稍微复杂的数据非常有帮助。我认为这不会被磁盘清理程序清除因为它存储在AppData(适用于Android)中.. 在此方法中,您的数据将存储在SQLite数据库中。其插件是SQFLite
  4. 这里可能需要放入的数据种类,就像数据库可以表示的一切一样广泛。

15

1
这对大型数据库来说是理想的吗? - temp_
1
@temp_ 我对iOS不是很了解。然而,在Android上,Shared Preferences绝对不适合大型数据库。它们被写成普通的xml文件到文件系统中,并在请求时从文件系统中读取。它们主要用于存储应用程序首选项和类似的东西。 - forgemo
这似乎更适用于共享首选项:https://pub.dev/packages/shared_preferences - Yster

14
您可以使用Localstorage
flutter pub add localstorage

1-pubspec.yaml中添加依赖项(根据最新版本更改)。

dependencies:
  ...
  localstorage: ^4.0.0+1

2- 然后运行以下命令

flutter packages get

第三步- 导入本地存储:

import 'package:localstorage/localstorage.dart';

4- 创建一个实例

class MainApp extends StatelessWidget {
  final LocalStorage storage = new LocalStorage('localstorage_app');
  ...
}

项目添加到本地存储:

void addItemsToLocalStorage() {
  storage.setItem('name', 'Abolfazl');
  storage.setItem('family', 'Roshanzamir');

  final info = json.encode({'name': 'Darush', 'family': 'Roshanzami'});
  storage.setItem('info', info);
}

从本地存储中获取一个项目:

void getitemFromLocalStorage() {
  final name = storage.getItem('name'); // Abolfazl
  final family = storage.getItem('family'); // Roshanzamir
  
  Map<String, dynamic> info = json.decode(storage.getItem('info'));
  final info_name=info['name'];
  final info_family=info['family'];
}

从本地存储中删除一个项目:

void removeItemFromLocalStorage() {
  storage.deleteItem('name');
  storage.deleteItem('family');
  storage.deleteItem('info');
}

1
我还没有尝试过这个库,但它似乎是一种使用唯一键在JSON中存储文件的方法。这看起来有点像NoSQL,但它缺少所有数据库操作,如查询和更新。这就是与sqllite相比的区别。 - Jason Ching
如何列出保存在JSON文件中的所有项目? - user1267779

13

如果您只需要存储简单的值,例如API令牌或登录数据(不包括密码!),这是我使用的方法:

import 'package:shared_preferences/shared_preferences.dart';

asyncFunc() async { // Async func to handle Futures easier; or use Future.then
  SharedPreferences prefs = await SharedPreferences.getInstance();
}
...

// Set
prefs.setString('apiToken', token);

// Get
String token = prefs.getString('apiToken');

// Remove
prefs.remove('apiToken');

别忘了在你的 pubspec.yaml 文件中添加 shared_preferences 依赖(保留原有空格格式):

dependencies:

  shared_preferences: any

8

1
Moor在Web上仍处于实验阶段。您无法在Web上编写文件。共享首选项不能保证写入。SQLite仅支持移动设备。这些都不是跨平台选项。 - Richard

4
我正在寻找一个既简单易用又具有一定安全性的本地存储解决方案。我发现的两个最合适的解决方案是flutter_secure_storage(由Raouf提到)用于小数据,以及hive用于大规模数据集。

3

2
我认为,如果你打算在本地存储大量数据,可以使用 sqflite 库。它非常容易设置,我个人用过一些测试项目,效果很好。
这是一个教程 - https://proandroiddev.com/flutter-bookshelf-app-part-2-personal-notes-and-database-integration-a3b47a84c57
如果你想把数据存储在云端,可以使用 Firebase。它是谷歌提供的可靠服务。

https://firebase.google.com/docs/flutter/setup


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接