内容简介:应用开发时会有很多的数据存储需求,这个时候就需要用到持久化存储技术,与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); }, ), ], ), ) ); } } 复制代码
运行效果如下:
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相关技术文章打开微信扫描二维码关注微信公众号获取。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 浅谈iOS持久化存储——沙盒存储
- Flutter持久化存储之数据库存储
- 深入浅出聊聊Kubernetes存储(二):搞定持久化存储
- kubernetes 持久化存储(二)
- kubernetes 持久化存储(一)
- 探讨分享 - 容器与持久化存储
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
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》 这本书的介绍吧!