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);
