Flutter 提供了三种数据持久化方法,即文件、SharedPreferences 与数据库。

文件

Flutter 提供了两种文件存储的目录,即临时(Temporary)目录与文档(Documents)目录:

临时目录是操作系统可以随时清除的目录,通常被用来存放一些不重要的临时缓存数据。这个目录在 iOS 上对应着 NSTemporaryDirectory 返回的值(网上搜集的信息,对 iOS 不熟悉故不确定对错),而在 Android上则对应着 getCacheDir 返回的值。

文档目录则是只有在删除应用程序时才会被清除的目录,通常被用来存放应用产生的重要数据文件。在 iOS上,这个目录对应着 NSDocumentDirectory (网上搜集的信息,对iOS不熟悉故不确定对错),而在 Android上则对应着 AppData 目录。

如何在Flutter中获取上述两个目录地址呢?这里使用到的是 path_provider库

先在pubspec.yaml中添加依赖,然后点击AndroidStudio右上角的 packages get

dependencies:

path_provider: ^1.6.5

接下来就可以获取到以上两个目录路径了:

// 获取临时目录

Directory tempDir = await getTemporaryDirectory();

String tempPath = tempDir.path;

// 获取文档目录

Directory appDocDir = await getApplicationDocumentsDirectory();

String appDocPath = appDocDir.path;

接下来我们通过示例来看一下效果。

示例

创建文件并写入数据,随后将数据读取出来。由于文件读写一般比较耗时且容易出错,为了保证程序的健壮性,需要异步Futures以及 try catch使用。

首先在文档目录创建文件:

Future get _localFile async {

// 存在文档目录

final directory = await getApplicationDocumentsDirectory();

final path = directory.path;

// 使用绝对路径

return File('$path/content.txt');

}

接着在文件中写入数据:

Future writeContent(String content) async {

// 获取到文件

final file = await _localFile;

// 执行写入

return file.writeAsString(content);

}

最后将上一步写入的数据读取出来:

Future readContent() async {

try {

// 获取到文件

final file = await _localFile;

// 执行读取

String contents = await file.readAsString();

return contents;

} catch (e) {

return "";

}

}

效果图:

SharedPreferences

文件比较适合大量的、有序的数据持久化,如果我们只是需要缓存少量的键值对信息(比如记录用户是否阅读了公告,或是简单的计数),则可以使用 SharedPreferences。

接下来我们通过示例来看一下效果。

示例

dependencies:

shared_preferences: ^0.5.6+3

然后往 SP 中写入数据:

// 获得实例

Future _prefs = SharedPreferences.getInstance();

// 写入数据

_prefs.then((sp) => {

sp.setString('hello', '你好 SharedPreferences')

});

最后将之前写入的数据读取出来:

// 获得实例

Future _prefs = SharedPreferences.getInstance();

// 取出数据

_prefs.then((sp) {

setState(() {

mContent = sp.getString('hello');// 通过可 key 取出 value

});

});

先看示例效果:

跳转网页那块有点慢,录制 gif 的时候直接跳过了,所以在详情页面会短暂显示空白

使用流程:

先获取到 SharedPrefernces 对象,

然后再点击搜索列表的 item 然后将数据存入到 SharedPrefernces中,

最后在历史面板展示 SharedPrefernces 中的数据。

数据库 sqlite

SharedPrefernces 的使用固然方便,但这种方式只适用于持久化少量数据的场景,我们并不能用它来存储大量数据。原因是在 Android中使用 SharedPrefernces 存储的文件过大会导致读取速度变慢还可能出现内存抖动问题,iOS不熟悉这块也没法描述。为了解决以上问题,通常会选用 sqlite 数据库来本地化存储稍大量的数据。

示例

往数据库中添加三个学生的数据,然后读取出学生的姓名。

1. 首先引入库:sqflite

dependencies:

...

sqflite: ^1.3.0

2. 创建数据库,并调用初始化方法,我这里是在initState()调用:

join 方法可能会爆红,在顶部引入path库即可

import 'package:path/path.dart';

Future initDataBase() async {

dataBase = await openDatabase(

join(await getDatabasesPath(), 'students_database.db'),

onCreate: (db, version) => db.execute(

"CREATE TABLE students(id TEXT PRIMARY KEY, name TEXT, score INTEGER)"),

onUpgrade: (db, oldVersion, newVersion) {

//dosth for migration

print("old:$oldVersion,new:$newVersion");

},

version: 1,

);

print("database:$dataBase");

}

// 调用初始化

@override

void initState() {

initDataBase();

super.initState();

}

3. 存入数据:

// 创建 Student 对象

class Student {

String id;

String name;

int score;

Student({

this.id,

this.name,

this.score,

});

factory Student.fromJson(Map parsedJson) {

return Student(

id: parsedJson['id'],

name: parsedJson['name'],

score: parsedJson['score'],

);

}

Map toJson() {

return {

'id': id,

'name': name,

'score': score,

};

}

}

// 插入数据库 中的 students 表

Future insertStudent(Student std) async {

await dataBase.insert(

'students',

std.toJson(),

conflictAlgorithm: ConflictAlgorithm.replace,

);

}

// 调用插入数据方法

insertData() async {

var student1 = Student(id: '0', name: '张三', score: 90);

var student2 = Student(id: '1', name: '李四', score: 80);

var student3 = Student(id: '2', name: '王五', score: 85);

// Insert a dog into the database.

await insertStudent(student1);

await insertStudent(student2);

await insertStudent(student3);

}

4. 取出数据:

// 查询 students 表的数据

Future> students() async {

final List> maps = await dataBase.query('students');

return List.generate(maps.length, (i) => Student.fromJson(maps[i]));

}

// 转为 string 输出

getStudents() async {

await students()

.then((list) => list.forEach((s) => sb.writeln(s.toJson().toString())));

setState(() {

mContext = sb.toString();

});

}

5. 关闭数据库:

@override

void dispose() {

dataBase.close();

super.dispose();

}

以上就是数据库的基本使用,使用步骤略有繁琐,我们可以封装了之后再使用。

封装之后使用,源码地址:

先看示例效果:

本地收藏数据库实现。跳转网页那块有点慢,录制 gif 的时候直接跳过了,所以在详情页面会短暂显示空白。

使用流程:

初始化数据库对象,这里在main.dart文件中初始化。具体的初始化逻辑在utils/provider.dart文件中

// 数据库初始化

await provider.init(true);

然后我们将常见的数据操作(增删改查)放在utils/sql.dart文件中,便于操作数据库。

接着就是具体的使用了。如收藏操作,在model/collect.dart文件中,先创建到 Collection 对象和在数据库中创建表格,并在里面实现model的数据库逻辑操作。

// 例如:插入新收藏

Future insert(Collection collection) {

var result =

sql.insert({'id': collection.id, 'title': collection.title, 'link':collection.link});

return result;

}

定义好逻辑操作之后,接着就是在合理的地方响应用户的输入了。这里是在详情页面用户点击收藏图标时调用model/collect.dart 中的 insert方法插入数据库。

// 插入操作

_collectionControl

.insert(Collection(

id: widget.id.toString(),

title: widget.title,

link: widget.link))

.then((result) {

if (this.mounted) {

setState(() {

_hasCollected = true;

});

print("收藏成功");

// 发送事件给 收藏页面,显示数据

if (ApplicationEvent.event != null) {

ApplicationEvent.event

.fire(CollectionEvent(widget.title, _link, false));

}

}

});

最后在views/collection_page.dart页面展示收藏的数据。

void _getList() {

_collectionList.clear();

_collectionControl.getAllCollection().then((resultList) {

resultList.forEach((item) {

_collectionList.add(item);

});

if (this.mounted) {

setState(() {

_collectionList = _collectionList;

});

}

});

}

本文同步分享在 博客“_龙衣”(CSDN)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

flutter可以用 mysql数据库_Flutter 本地数据存储(文件、SharedPreferences 、数据库 sqlite)使用示例...相关推荐

  1. Softing dataFEED OPC Suite将西门子PLC数据存储到Oracle数据库中

    一 背景 现代工业产品不仅生产批量大,而且过程自动化程度高,这对于用户追溯产品设计与制造过程中产生的数据而言,无疑是个新的挑战.与此同时,制造商们对产品制造过程中产生的大量工艺数据也愈发重视,并不断寻 ...

  2. android 储存方案,Android本地数据存储方案(一)

    Android系列的博客主要是记录和总结自己在平时学习之中遇到的问题,方便日后用到时查看,同时也希望对读者有所帮助.不足之处,欢迎指正~ 在说到Android数据存储之前,先提一下数据持久化,所谓数据 ...

  3. iOS本地数据存储安全

    iOS本地数据存储安全 移动APP通常会在设备本地存储一些数据,这可以为程序执行.更良好地性能或离线访问提供支持.由于移动设备使用地越来越广泛,设备失窃的风险也越来越大,因此不安全的本地数据存储已成为 ...

  4. Windows 8 应用开发 - 本地数据存储

    原文:Windows 8 应用开发 - 本地数据存储 在应用中通常会遇到用户主动或被动存储信息的情况,当应用关闭后这些数据仍然会存储在本地设备上,用户下次重新激活应用时会自动加载这些数据.下面将通过一 ...

  5. iOS APP之本地数据存储(译)

    最近工作中完成了项目的用户信息本地存储,查阅了一些本地存储加密方法等相关资料.期间发现了一个来自印度理工学院(IIT)的信息安全工程师的个人博客,写了大量有关iOS Application secur ...

  6. 白鹭本地数据存储操作代码实例

    白鹭引擎 版本:5.2.8 描述:白鹭本地数据存储操作代码实例 本地数据的增删改查函数 /*** 数据存储函数*/private save_key(key_name:string,key_value: ...

  7. Android本地数据存储: Reservoir

    一:前言 今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名.密码这样的.其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用 ...

  8. Unity3D 数据转换 本地数据存储、Excel表格数据读取与多语言本地化

    Unity3D 项目框架相关 数据转换 TDataConvertion XML本地数据存储 TGameSave Excel读表工具 TExcel 多语言本地化 TLocalization 范例工程: ...

  9. Unity 之 转微信小游戏本地数据存储方法分享

    Unity 之 转微信小游戏本地数据存储 问题背景 微信小游戏读写本地文件 WebGL平台的一些限制 报错查看方法分享 问题背景 近期在将Unity转换为小游戏的时候发现在读写本地文件的时候,使用Ap ...

最新文章

  1. share extension 不显示_你所不知道的网红小酒馆Helens
  2. python程序保存_初识python 文件读取 保存
  3. Excel 公式 两个时间比大小
  4. linux内核网络协议栈--数据包的skb桥转发蓝图(二十六)
  5. python学习之老男孩python全栈第九期_day004知识点总结
  6. 最近了解过的一个支付接口
  7. letter-spacing和word-spacing之间的区别
  8. 视频教程-Protel99se电路设计速成-智能硬件
  9. 分区助手扩大c盘后自动修复_【分区助手】如何扩大C盘容量?
  10. Win10 - 使用‘Alt+Tab’不能切换窗口及更改切换风格
  11. ​交大最新研究:长江学者和杰青平均在47岁前达到科研产出高峰
  12. 虚拟模拟器可以用服务器,云服务器可以用什么模拟器
  13. termux python 打开摄像头_python+opencv 电脑调用手机的摄像头
  14. 蓝牙无线测试相关参数与方法
  15. 【功能】:前台上传文件(txt,xls,xlsx,csv,pdf)五种格式的文件 后台java解析文件,并且判断文件内容是否为零字节
  16. 百度paddlepaddle入门讲解第一周内容
  17. js+html+css+jQuery实现简单购物车
  18. python模块cpca修改源码支持国外地址解析
  19. 非LL(1)文法到LL(1)文法的等价变换
  20. 如何使用CAD编辑器来画箭头

热门文章

  1. php逐级审批,php 审批流程管理
  2. ubuntu16.04删除用户及用户目录(高效方法)
  3. CSS3 + JS 数字滚动效果
  4. 软件测试缺陷等级划分_众测项目中功能测试、安全测试和兼容性缺陷等级区分定义...
  5. mysql pom.xml版本号_pom.xml · 我是一只小小小鸟/canal_mysql_elasticsearch_sync - Gitee.com...
  6. 开源机器学习数据库OpenMLDB贡献者计划全面启动
  7. Dword shoot
  8. 用hexo在gitcafe上搭个人博客
  9. JS函数声明和预解析的理解
  10. powershell 解压RAR文件(简易版)