Shared Preferences
在 Flutter 中,可以使用Shared Preferences plugin
来达到与NSUserDefaults
相似的功能。它包含了 NSUserDefaluts 以及 Android 上等价的 SharedPreferences 的功能。
使用它需要将shared_preferences
引入pubspec.yaml文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class SharedPreferenceSampleAppPage extends StatelessWidget {
Future _incrementCounter() async {
SharedPreferences pref = await SharedPreferences.getInstance();
// ?? 等价于 iOS中的 ?:
int counter = (pref.getInt('counter') ?? 0) + 1;
print('Pressed $counter times');
await pref.setInt('counter', counter);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Shared Preferences Demo'),
),
body: Center(
child: RaisedButton(
child: Text('Increment Counter'),
onPressed: _incrementCounter,
),
),
);
}
}
如果报以下错误,需要重新打开工程:
1
MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
Sqflite
另外,iOS中的CoreData
(实质上也是对SQLite的封装),在Flutter中使用SQFlite
来代替。
- sqflite支持事务和批次处理
- 打开期间自动版本管理
- 支持插入/查询/更新/删除查询的助手
- 支持在iOS和Android上的后台线程中执行数据库操作
Sqflite用法
首先需要导入sqflite.dart
1
import 'package:sqflite/sqflite.dart';
打开数据库
需要现货区数据库路径,这是Android上的默认数据库目录和为iOS的Documents目录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 打开数据库
open() async {
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo.db');
print('path: $path');
// 删除数据库
// await deleteDatabase(path);
db = await openDatabase(
path,
version: 1,
onCreate: (Database database, int version) async {
await database.execute(
// sql语句 创建表
'CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)'
);
}
);
}
关闭数据库
许多应用程序使用数据库期间不需要关闭它(当应用程序终止时它将被关闭)。如果要释放资源,可以关闭数据库。
1
await db.close();
基本使用
增
1
2
3
4
5
6
7
8
9
10
11
12
13
14
insert() async {
// 使用事务添加两条记录
await db.transaction((txn) async {
int id1 = await txn.rawInsert(
'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)'
);
print('inserted1:$id1');
int id2 = await txn.rawInsert(
'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)', ['another name', 5678, 3.14]
);
print('inserted2:$id2');
});
}
删
1
2
3
4
5
6
delete() async {
int result = await db.rawDelete(
'DELETE FROM Test WHERE name = ?', ['some name',]
);
print('delete result:$result');
}
改
1
2
3
4
5
6
update() async {
int result = await db.rawUpdate(
'UPDATE Test SET name = ?, VALUE = ? WHERE name = ?', ['updated name', '7890', 'another name']
);
print('update result:$result');
}
查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
lookup() async {
List<Map> list = await db.rawQuery(
'SELECT * FROM Test'
);
print('All Datas: $list');
// 指定条件
List<Map> expectedList = await db.rawQuery(
'SELECT * FROM Test WHERE name = ? ORDER BY id DESC', ['updated name',]
);
print('ExpectedList : $expectedList');
// 查询count
int count = Sqflite.firstIntValue(await db.rawQuery(
'SELECT COUNT(*) FROM Test'
));
print('count = $count');
}
批量支持:
1
2
3
4
5
batch = db.batch();
batch.insert('Test', {'name': 'item'});
batch.update('Test', {'name': 'new_item'}, where: 'name = ?', whereArgs: ['item']);
batch.delete('Test', where: 'name = ?', whereArgs: ['item']);
results = await batch.commit();
如果不关心操作结果,可以使用下面方法来提高性能:
1
await batch.commit(noResult: true);
在事务中,事务提交之前不会提交批处理:
1
2
3
4
5
6
7
8
9
10
11
await database.transaction((txn) async {
var batch = txn.batch();
// ...
// commit but the actual commit will happen when the transaction is committed
// however the data is available in this transaction
await batch.commit();
// ...
});
默认情况下,批处理在遇到错误时会立即停止(通常会还原未提交的更改)。也可以使用下面方法来忽略错误(即使一个操作失败也会运行并提交每个成功的操作):
1
await batch.commit(continueOnError: true);