Flutter 数据存储--shared_preferences使用详情
1.shared_preferences介绍
shared_preferences
主要的作用是用于将数据异步持久化到磁盘,因为持久化数据只是存储到临时目录,当app删除时该存储的数据就是消失,web开发时清除浏览器存储的数据也将消失。
支持存储类型:
- bool
- int
- double
- string
- stringList
shared_preferences应用场景
主要用于持久化数据,如持久化用户信息、列表数据等。
持久化用户信息
因为用户信息基本是不改变的,而在一个应用程序中常常会有多个页面需要展示用户信息,我们不可能每次都去获取接口,那么本地持久化就会变得很方便。
持久化列表数据
为了给用户更好的体验,在获取列表数据时我们常常会先展示旧数据,带给用户更好的体验,不至于一打开页面就是空白的,当我们采用持久化列表数据后,可以直接先展示本地数据,当网络数据请求回来后在进行数据更新。
shared_preferences使用的对应类库
我们知道每个平台持久化数据的方式都不一样,而shared_preferences
针对不同的平台封装了一个通用的类库,接下来我们看看不同平台下他们使用的库:
- iOS: NSUserDefaults
- Android: SharedPreferences
- Web: localStorage
- Linux: FileSystem(保存数据到本地系统文件库中)
- Mac OS: FileSystem(保存数据到本地系统文件库中)
- Windows: FileSystem(保存数据到本地系统文件库中)
2.shared_preferences基本使用
导入头文件
import 'package:shared_preferences/shared_preferences.dart';
获取实例对象
SharedPreferences? sharedPreferences = await SharedPreferences.getInstance();
2.1.持久化数据的存储和读取
我们可以通过sharedPreferences
的实例化对象调用对应的set
方法设置持久化数据,通过get方法进行获取.
import 'package:flutter/material.dart';import 'package:shared_preferences/shared_preferences.dart';class SharedPreferencesExample extends StatefulWidget { @override _SharedPreferencesExampleState createState() => _SharedPreferencesExampleState();}class _SharedPreferencesExampleState extends State { SharedPreferences? sharedPreferences; // 设置持久化数据 void _setData() async { // 实例化 sharedPreferences = await SharedPreferences.getInstance(); // 设置string类型 await sharedPreferences?.setString("name", "Jimi"); // 设置int类型 await sharedPreferences?.setInt("age", 18); // 设置bool类型 await sharedPreferences?.setBool("isTeacher", true); // 设置double类型 await sharedPreferences?.setDouble("height", 1.88); // 设置string类型的数组 await sharedPreferences?.setStringList("action", ["吃饭", "睡觉", "打豆豆"]); setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("SharedPreferences"), ), floatingActionButton: FloatingActionButton( onPressed: _setData, child: Icon(Icons.add), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text("名字: ${sharedPreferences?.getString("name") ?? ""}", style: TextStyle( color: Colors.blue, fontSize: 20 ), ), SizedBox(height: 20,), Text("年龄: ${sharedPreferences?.getInt("age") ?? ""}", style: TextStyle( color: Colors.red, fontSize: 20 ), ), SizedBox(height: 20,), Text("是老师吗?: ${sharedPreferences?.getBool("isTeacher") ?? ""}", style: TextStyle( color: Colors.orange, fontSize: 20 ), ), SizedBox(height: 20,), Text("身高: ${sharedPreferences?.getDouble("height") ?? ""}", style: TextStyle( color: Colors.pink, fontSize: 20 ), ), SizedBox(height: 20,), Text("我正在: ${sharedPreferences?.getStringList("action") ?? ""}", style: TextStyle( color: Colors.purple, fontSize: 20 ), ), ], ), ), ); }}
2.2. 获取持久化数据中所有存入的key
List keys = sharedPreferences?.getKeys().toList() ?? [];print(keys);// 控制台输出[name, age, isTeacher, height, action]
2.3.判断持久化数据中是否包含某个key
bool isContainKey = sharedPreferences?.containsKey("name") ?? false;print(isContainKey);// 控制台输出flutter: true
2.4.删除持久化数据中某个key
bool isRemoveKey = await sharedPreferences?.remove("name") ?? false;print(isRemoveKey);// 控制台输出flutter: true
2.5.清除所有持久化数据
bool isClearAllKey = await sharedPreferences?.clear() ?? false;print(isClearAllKey);// 控制台输出flutter: true
2.6.重新加载所有数据(仅重载运行时)
await sharedPreferences?.reload();
3.shared_preferences封装
我们在使用shared_preferences
时每次都需要去获取它的实例,如果多个地方用到,那么每次都要实例化一次。这样代码的可读性差,后期的维护成本也变得很高,而且还不支持存储Map
类型,所以接下来我们对shared_preferences
来封装一个通用而且使用更简单的库。
使用单例模式进行shared_preferences封装
因为我们获取的都是同一个实例,所以采用单例模式来进行封装最好,而且获取实例是异步的,所以我们在应用程序启动时先初始化,这样使用起来更加的方便。
创建单例类
因为我们代码都是采用了空安全,所以空安全里面有个非常重要的属性late
来延迟加载我们实例,如下.
class JSpUtil { JSpUtil._internal(); factory JSpUtil() => _instance; static late final JSpUtil _instance = JSpUtil._internal();}
初始化shared_preferences
因为采用单例模式,所以在获取唯一实例的时候我们在入口统一获取一次即可。
static late SharedPreferences _preferences;static Future getInstance() async { _preferences = await SharedPreferences.getInstance(); return _instance;}
封装方式一:对应get、set方法
/// 根据key存储int类型static Future setInt(String key, int value) { return _preferences.setInt(key, value);}/// 根据key获取int类型static int? getInt(String key, {int defaultValue = 0}) { return _preferences.getInt(key) ?? defaultValue;}/// 根据key存储double类型static Future setDouble(String key, double value) { return _preferences.setDouble(key, value);}/// 根据key获取double类型static double? getDouble(String key, {double defaultValue = 0.0}) { return _preferences.getDouble(key) ?? defaultValue;}/// 根据key存储字符串类型static Future setString(String key, String value) { return _preferences.setString(key, value);}/// 根据key获取字符串类型static String? getString(String key, {String defaultValue = ""}) { return _preferences.getString(key) ?? defaultValue;}/// 根据key存储布尔类型static Future setBool(String key, bool value) { return _preferences.setBool(key, value);}/// 根据key获取布尔类型static bool? getBool(String key, {bool defaultValue = false}) { return _preferences.getBool(key) ?? defaultValue;}/// 根据key存储字符串类型数组static Future setStringList(String key, List value) { return _preferences.setStringList(key, value);}/// 根据key获取字符串类型数组static List getStringList(String key, {List defaultValue = const []}) { return _preferences.getStringList(key) ?? defaultValue;}/// 根据key存储Map类型static Future setMap(String key, Map value) { return _preferences.setString(key, json.encode(value));}/// 根据key获取Map类型static Map getMap(String key) { String jsonStr = _preferences.getString(key) ?? ""; return jsonStr.isEmpty ? Map : json.decode(jsonStr);}
封装方式二:统一set、get方法
/// 通用设置持久化数据static setLocalStorage(String key, T value) { String type = value.runtimeType.toString(); switch (type) { case "String": setString(key, value as String); break; case "int": setInt(key, value as int); break; case "bool": setBool(key, value as bool); break; case "double": setDouble(key, value as double); break; case "List": setStringList(key, value as List); break; case "_InternalLinkedHashMap": setMap(key, value as Map); break; }}/// 获取持久化数据static dynamic getLocalStorage(String key) { dynamic value = _preferences.get(key); if (value.runtimeType.toString() == "String") { if (_isJson(value)) { return json.decode(value); } } return value;}
两种封装的使用方式
// 设置String类型await JSpUtil.setString("name", "Jimi");// 设置int类型await JSpUtil.setInt("age", 18);// 设置bool类型await JSpUtil.setBool("isTeacher", true);// 设置double类型await JSpUtil.setDouble("height", 1.88);// 设置string类型的数组await JSpUtil.setStringList("action", ["吃饭", "睡觉", "打豆豆"]);// 设置Map类型await JSpUtil.setMap("weight", {"weight": 112});JSpUtil.setLocalStorage("name", "Jimi");JSpUtil.setLocalStorage("age", 18);JSpUtil.setLocalStorage("isTeacher", true);JSpUtil.setLocalStorage("height", 1.88);JSpUtil.setLocalStorage("action", ["吃饭", "睡觉", "打豆豆"]);JSpUtil.setLocalStorage("weight", {"weight": "112"});JSpUtil.getLocalStorage("name");JSpUtil.getLocalStorage("age");JSpUtil.getLocalStorage("isTeacher");JSpUtil.getLocalStorage("height");JSpUtil.getLocalStorage("action");JSpUtil.getLocalStorage("weight");// 获取磁盘中所有存入的keyList keys = JSpUtil.getKeys().toList();print(keys);// 持久化数据中是否包含某个keybool isContainKey = JSpUtil.containsKey("name");print(isContainKey);// 删除持久化数据中某个keybool isRemoveKey = await JSpUtil.remove("name");print(isRemoveKey);// 清除所有持久化数据bool isClearAllKey = await JSpUtil.clear();print(isClearAllKey);// 重新加载所有数据,仅重载运行时await JSpUtil.reload();
获取值的方式
Text("名字: ${JSpUtil.getString("name")}", style: TextStyle( color: Colors.blue, fontSize: 20 ), ),SizedBox(height: 20,),Text("年龄: ${JSpUtil.getInt("age")}", style: TextStyle( color: Colors.red, fontSize: 20 ), ),SizedBox(height: 20,),Text("是老师吗?: ${JSpUtil.getBool("isTeacher")}", style: TextStyle( color: Colors.orange, fontSize: 20 ), ),SizedBox(height: 20,),Text("身高: ${JSpUtil.getDouble("height")}", style: TextStyle( color: Colors.pink, fontSize: 20 ), ),SizedBox(height: 20,),Text("我正在: ${JSpUtil.getStringList("action")}", style: TextStyle( color: Colors.purple, fontSize: 20 ), ),
来源地址:https://blog.csdn.net/eastWind1101/article/details/127977741
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341