Flutter持久化存储之key-value存储

栏目: IOS · 发布时间: 6年前

内容简介:应用开发时会有很多的数据存储需求,这个时候就需要用到持久化存储技术,与iOS、安卓一样,Flutter中也有很多种持久化存储方式,比如key-value存储、文件存储、数据库存储等,但其实质都是通过平台对应的模块来实现的,本篇我们将带大家一起了解key-value存储的应用。key-value存储主要是平台提供特定的api来供我们操作,其本质依然是将数据存储到特定文件中,只不过这些工作都由平台帮我们做,比如iOS平台中的NSUserDefaults、安卓平台的SharedPreferences等等。Flut

应用开发时会有很多的数据存储需求,这个时候就需要用到持久化存储技术,与iOS、安卓一样,Flutter中也有很多种持久化存储方式,比如key-value存储、文件存储、数据库存储等,但其实质都是通过平台对应的模块来实现的,本篇我们将带大家一起了解key-value存储的应用。

key-value存储介绍

key-value存储主要是平台提供特定的api来供我们操作,其本质依然是将数据存储到特定文件中,只不过这些工作都由平台帮我们做,比如iOS平台中的NSUserDefaults、安卓平台的SharedPreferences等等。Flutter中可以使用shared_preferences插件来实现key-value存储,主要存储数据类型包括bool,int,double,String,List等等。

key-value存储使用

引入插件

在pubspec.yaml文件中添加shared_preferences插件,如下:

dependencies:
  flutter:
    sdk: flutter
  #shared_preferences插件
  shared_preferences: 0.4.3
复制代码

然后命令行执行 flutter packages get 即可将插件下载到本地

使用方法

插件引入到项目后,在使用的dart文件中导入shared_preferences.dart文件

import 'package:shared_preferences/shared_preferences.dart';
复制代码

具体使用如下,获取SharedPreferences的单例方法是一个异步方法,所以在使用时需要注意使用await获取其真实对象,如下::

Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

//保存数据
void saveMethodName() async {
    SharedPreferences prefs = await _prefs;
    prefs.setString("strKey", "strValue");
    prefs.setInt("intKey", "intValue");
    .
    .
}

//获取数据
void initFromCache() async {
    SharedPreferences prefs = await _prefs;
    String strValue = prefs.getString("strKey");
    int intValue = prefs.getInt("intKey");
    .
    .
}
复制代码

举个栗子

import 'package:shared_preferences/shared_preferences.dart';

class TestPersistent extends StatefulWidget {
  final String title;

  TestPersistent({Key key, this.title}):super(key: key);

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return TestPersistentState();
  }

}

class TestPersistentState extends State<TestPersistent> {
  var controller = TextEditingController();
  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  bool mt = false;
  bool ds = false;
  bool ltb = false;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    initFromCache();
  }

  @override
  void dispose() {
    super.dispose();
    controller = null;
  }

  //从缓存中获取信息填充
  void initFromCache() async {
    final SharedPreferences prefs = await _prefs;
    final nickname = prefs.getString("nickname");
    final mt = prefs.getBool("mt");
    final ds = prefs.getBool("ds");
    final ltb = prefs.getBool("ltb");
    
    //获取到缓存中的值后,使用setState更新界面信息
    setState(() {
      controller.text = (nickname == null ? "" : nickname);
      this.mt = (mt == null ? false : mt);
      this.ds = (ds == null ? false : ds);
      this.ltb = (ltb == null ? false : ltb);
    });
  }

  //保存界面的输入选择信息
  void saveInfo(String nickname) async {
    final SharedPreferences prefs = await _prefs;
    prefs.setString("nickname", nickname);
    prefs.setBool("mt", mt);
    prefs.setBool("ds", ds);
    prefs.setBool("ltb", ltb);
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(this.widget.title),
      ),
      body: Container(
        padding: EdgeInsets.all(15),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            TextField(
              controller: controller,
              decoration: InputDecoration(
                labelText: 'Nickname:',
                hintText: 'Please input nickname',
              ),
            ),
            Text('最近你使用过哪一款新的社交软件'),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Text('马桶MT'),
                Switch(
                  value: mt,
                  onChanged: (isChanged) {
                    setState(() {
                      this.mt = isChanged;
                    });
                  },
                )
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Text('多闪'),
                Switch(
                  value: ds,
                  onChanged: (isChanged) {
                    setState(() {
                      this.ds = isChanged;
                    });
                  },
                )
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Text('聊天宝'),
                Switch(
                  value: ltb,
                  onChanged: (isChanged) {
                    setState(() {
                      this.ltb = isChanged;
                    });
                  },
                )
              ],
            ),
            MaterialButton(
              child: Text('保存'),
              onPressed: () {
                print(controller.text);
                saveInfo(controller.text);
              },
            ),
          ],
        ),
      )
    );
  }

}
复制代码

运行效果如下:

Flutter持久化存储之key-value存储

shared-preferences实现原理

该插件的实现原理很简单,通过源码分析,我们发现主要是通过channel与原生平台进行交互,通过iOS平台的NSUserDefaults、安卓平台的SharedPreferences来实现具体数据存取操作。

iOS平台分析

//iOS平台插件源码

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
  FlutterMethodChannel *channel =
      [FlutterMethodChannel methodChannelWithName:CHANNEL_NAME binaryMessenger:registrar.messenger];
  [channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
    NSString *method = [call method];
    NSDictionary *arguments = [call arguments];

    if ([method isEqualToString:@"getAll"]) {
      result(getAllPrefs());
    } else if ([method isEqualToString:@"setBool"]) {
      NSString *key = arguments[@"key"];
      NSNumber *value = arguments[@"value"];
      [[NSUserDefaults standardUserDefaults] setBool:value.boolValue forKey:key];
      result(@YES);
    } else if ([method isEqualToString:@"setInt"]) {
      NSString *key = arguments[@"key"];
      NSNumber *value = arguments[@"value"];
      // int type in Dart can come to native side in a variety of forms
      // It is best to store it as is and send it back when needed.
      // Platform channel will handle the conversion.
      [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
      result(@YES);
    } else {
    	.
    	.
    	.
    }
  }];
}
复制代码

由源码可以看出,flutter中代码通过传输指定的method和对应的存储数据给iOS平台,iOS端接收到指令数据后会根据方法名来判断执行操作的类型,然后进行对应的操作,比如setBool就会通过[NSUserDefaults standardUserDefaults]对象来保存bool类型的数据。

安卓平台

private final android.content.SharedPreferences preferences;

  public static void registerWith(PluginRegistry.Registrar registrar) {
    MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL_NAME);
    SharedPreferencesPlugin instance = new SharedPreferencesPlugin(registrar.context());
    channel.setMethodCallHandler(instance);
  }

  private SharedPreferencesPlugin(Context context) {
    preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
  }
  
  @Override
  public void onMethodCall(MethodCall call, MethodChannel.Result result) {
    String key = call.argument("key");
    boolean status = false;
    try {
      switch (call.method) {
        case "setBool":
          status = preferences.edit().putBoolean(key, (boolean) call.argument("value")).commit();
          break;
        case "setDouble":
          float floatValue = ((Number) call.argument("value")).floatValue();
          status = preferences.edit().putFloat(key, floatValue).commit();
          break;
        	.
        	.
        	.
      }
      result.success(status);
    } catch (IOException e) {
      result.error("IOException encountered", call.method, e);
    }
  }
复制代码

安卓端和iOS端类似,会通过一个SharedPreferences实例对象preferences来根据指定method做对应的存取数据操作。

写在最后

本篇对持久化存储key-value做了简要的使用介绍,整体使用和原生一样比较简单,只要熟悉几个api就OK了,key-value主要用于保存一些简单的配置信息或状态数据,轻量级的数据持久化非常合适,针对数量级比较大的数据存储场景来说,我们就要使用到文件存储和数据库存储了,下一篇我们将带大家一起学习file存储,敬请期待!

说明:

文章转载自对应的“Flutter编程指南”微信公众号,更多Flutter相关技术文章打开微信扫描二维码关注微信公众号获取。

Flutter持久化存储之key-value存储

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Spring in Action

Spring in Action

Craig Walls / Manning Publications / 2011-6-29 / USD 49.99

Spring in Action, Third Edition has been completely revised to reflect the latest features, tools, practices Spring offers to java developers. It begins by introducing the core concepts of Spring and......一起来看看 《Spring in Action》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具