一、shared_preferences 插件

shared_preferences 是 Flutter 提供的 key-value 存储插件,能够将数据持久化到磁盘中。

在 iOS 上封装的是 NSUserDefault 在 android 上封装的是 SharedPreferences

如果要使用,需要在 pubspec.yaml 中添加 shared_preferences 依赖

  shared_preferences: ^0.5.3+1

二、使用 shared_preferences

1、获取实例

要使用 shared_preferences 需要首先拿到 instance,提供了 getInstance() 方法:

  static Future<SharedPreferences> getInstance() async {
    if (_instance == null) {
      final Map<String, Object> preferencesMap =
          await _getSharedPreferencesMap();
      _instance = SharedPreferences._(preferencesMap);
    }
    return _instance;
  }

方法是异步的,因此在使用的时候也需要异步获取

  void _getInstance() async {
    _prefs = await SharedPreferences.getInstance();
  }

如果需要在 StatefulWidget 中使用,可以在 initState 中或者构造函数拿到并且初始化

  _PreferencesDemoState() {
    _key = 'name';
    _value = 'postbird-value';
    _getInstance();
  }

2、存储数据

SharedPreferences 提供了 setIntsetBoolsetStringsetStringList 等方法,用来设置特定类型的数据,而本身这些方法是基于 _setValue 这个私有方法实现的,最终通过 involeMethod(set$valueType) 调用 native 方法

  Future<bool> _setValue(String valueType, String key, Object value) {
    final Map<String, dynamic> params = <String, dynamic>{
      'key': '$_prefix$key',
    };
    if (value == null) {
      _preferenceCache.remove(key);
      return _kChannel
          .invokeMethod<bool>('remove', params)
          .then<bool>((dynamic result) => result);
    } else {
      _preferenceCache[key] = value;
      params['value'] = value;
      return _kChannel
          .invokeMethod<bool>('set$valueType', params)
          .then<bool>((dynamic result) => result);
    }
  }

存储数据:

  void _savePressedHandle() {
    _value = DateTime.now().toString();
    _prefs.setString(_key, _value);
    print(_prefs);
    Scaffold.of(context).hideCurrentSnackBar();
    Scaffold.of(context).showSnackBar(SnackBar(content: Text('set succssed')));
  }

3、获取数据

和 set 类似,初次之外,还包括 getString / getInt / getDouble 等方法

  void _getPressedHandle() {
    final name = _prefs.getString(_key);
    print(name);
    Scaffold.of(context).hideCurrentSnackBar();
    Scaffold.of(context).showSnackBar(SnackBar(content: Text('get $name')));
  }    

4、getKeys、containsKey

这些是提供的一些辅助类的方法,用于获取所有的 key 或者判断是否存在 key

5、移除数据

  void _removePressedHandle() {
    final res = _prefs.remove(_key);
    print(res);
    Scaffold.of(context).hideCurrentSnackBar();
    Scaffold.of(context).showSnackBar(SnackBar(content: Text('remove $_key')));
  }

三、效果

3.gif

四、完整代码实例

https://github.com/postbird/FlutterHelloWorldDemo/blob/master/demo1/lib/bak/main.54-SharedPreference-%E9%94%AE%E5%80%BC%E5%AD%98%E5%82%A8.dart