Flutter 使用 shared_preferences 实现数据持久化

Flutter 中 shared_preferences 的使用

在移动应用开发中,我们经常需要将一些数据持久化保存,以便在应用重启或用户再次使用时能够恢复这些数据。shared_preferences 是 Flutter 提供的一个简单易用的库,专门用于在应用本地存储轻量级的键值对数据。

一. 简介

shared_preferences 是一个用于存储少量数据的轻量级插件,适用于保存简单的键值对数据,如布尔值、整数、字符串和字符串列表等。例如:保存应用的配置参数、用户偏好设置以及一些简单的状态数据。数据可能会异步持久化到磁盘,并且不能保证写入返回后会持久化到磁盘,因此该插件不得用于存储关键数据。

二. 安装shared_preferences

首先,我们需要将 shared_preferences 库添加到项目的 pubspec.yaml 文件中:

	dependencies:
	  flutter:
	    sdk: flutter
	  shared_preferences: ^2.3.1

运行 flutter pub get 命令来安装依赖。

三. 基本用法

支持的数据类型为 int 、 double 、 bool 、 String 和 List 。

  1. 存储数据
	final SharedPreferences prefs = await SharedPreferences.getInstance();
	
	 prefs.setInt('counter', 10);
	 prefs.setBool('repeat', true);
	 prefs.setDouble('decimal', 1.5);
	 prefs.setString('action', 'Start');
	 prefs.setStringList('items', <String>['Earth', 'Moon', 'Sun']);
	
  1. 读取数据
	
	final int? counter = prefs.getInt('counter');
	final bool? repeat = prefs.getBool('repeat');
	final double? decimal = prefs.getDouble('decimal');
	final String? action = prefs.getString('action');
	final List<String>? items = prefs.getStringList('items');
	

例子:假设我们想要保存一个布尔值表示用户是否已登录:

	import 'package:flutter/material.dart';
	import 'package:shared_preferences/shared_preferences.dart';
	
	class MyHomePage extends StatefulWidget {
	  
	  _MyHomePageState createState() => _MyHomePageState();
	}
	
	class _MyHomePageState extends State<MyHomePage> {
	  bool _isLoggedIn = false;
	
	  
	  void initState() {
	    super.initState();
	    _loadLoginStatus();
	  }
	
	  // 加载登录状态
	  _loadLoginStatus() async {
	    SharedPreferences prefs = await SharedPreferences.getInstance();
	    setState(() {
	      _isLoggedIn = (prefs.getBool('isLoggedIn') ?? false);
	    });
	  }
	
	  // 保存登录状态
	  _saveLoginStatus(bool value) async {
	    SharedPreferences prefs = await SharedPreferences.getInstance();
	    prefs.setBool('isLoggedIn', value);
	  }
	
	  
	  Widget build(BuildContext context) {
	    return Scaffold(
	      appBar: AppBar(
	        title: Text("SharedPreferences Example"),
	      ),
	      body: Center(
	        child: Column(
	          mainAxisAlignment: MainAxisAlignment.center,
	          children: [
	            Text(
	              _isLoggedIn ? "Logged In" : "Logged Out",
	              style: TextStyle(fontSize: 24),
	            ),
	            SizedBox(height: 20),
	            ElevatedButton(
	              onPressed: () {
	                setState(() {
	                  _isLoggedIn = !_isLoggedIn;
	                  _saveLoginStatus(_isLoggedIn);
	                });
	              },
	              child: Text(_isLoggedIn ? "Logout" : "Login"),
	            ),
	          ],
	        ),
	      ),
	    );
	  }
	}
	_loadLoginStatus() async {
	  SharedPreferences prefs = await SharedPreferences.getInstance();
	  setState(() {
	    _isLoggedIn = (prefs.getBool('isLoggedIn') ?? false);
	  });
	}

四. 清除数据

	final SharedPreferences prefs = await SharedPreferences.getInstance();
	// 清除特定数据
	prefs.remove('counter');	
	// 清除所有数据
	prefs.clear();

SharedPreferencesAsync 允许用户直接调用平台来获取设备上保存的最新偏好设置,但代价是异步,速度比使用缓存版本慢一点。这对于可以由其他系统或隔离区更新的偏好设置很有用,因为更新缓存会使缓存失效。

	final SharedPreferencesAsync asyncPrefs = SharedPreferencesAsync();
	
	await asyncPrefs.setBool('repeat', true);
	await asyncPrefs.setString('action', 'Start');
	
	final bool? repeat = await asyncPrefs.getBool('repeat');
	final String? action = await asyncPrefs.getString('action');
	
	await asyncPrefs.remove('repeat');
	
	// Any time a filter option is included as a method parameter, strongly consider
	// using it to avoid potentially unwanted side effects.
	await asyncPrefs.clear(allowList: <String>{'action', 'repeat'});

SharedPreferencesWithCache 建立在 SharedPreferencesAsync 之上,允许用户同步访问本地缓存的偏好设置副本。这与旧 API 类似,但现在可以使用不同的参数多次实例化。

	final SharedPreferencesWithCache prefsWithCache =
	    await SharedPreferencesWithCache.create(
	  cacheOptions: const SharedPreferencesWithCacheOptions(
	    // When an allowlist is included, any keys that aren't included cannot be used.
	    allowList: <String>{'repeat', 'action'},
	  ),
	);
	
	await prefsWithCache.setBool('repeat', true);
	await prefsWithCache.setString('action', 'Start');
	
	final bool? repeat = prefsWithCache.getBool('repeat');
	final String? action = prefsWithCache.getString('action');
	
	await prefsWithCache.remove('repeat');
	
	// Since the filter options are set at creation, they aren't needed during clear.
	await prefsWithCache.clear();

五. 存储位置

平台SharedPreferencesSharedPreferencesAsync/WithCache
AndroidSharedPreferencesDataStore Preferences 数据存储首选项
iOSNSUserDefaults NSNSUserDefaults NS
macOSNSUserDefaults NSNSUserDefaults NS
LinuxIn the XDG_DATA_HOME directoryIn the XDG_DATA_HOME directory
WebLocalStorageLocalStorage
WindowsAppData目录中AppData目录中

六. 优缺点

优点

  • 简单易用:通过键值对的方式存储和读取数据,非常直观。
  • 轻量级:适合存储少量的数据,如用户偏好设置、简单的配置信息等。相比于数据库,它的资源占用更少,性能较高。
  • 跨平台支持: 支持 iOS、Android 和 Web 平台,可以在不同平台上使用相同的代码来进行数据持久化存储。
  • 异步操作:存储和读取操作都是异步进行的,避免了主线程的阻塞,保证了应用的流畅性。
  • 无外部依赖:不依赖于其他外部库或服务,只需将其添加到项目依赖中即可使用,使用起来非常方便。

缺点

  • 数据量有限:适用于存储轻量级的数据,通常是少量的键值对。不适合存储大量数据或复杂的数据结构(如大型 JSON 对象、二进制文件等)。
  • 性能限制:频繁读取或写入大量数据时,性能可能会受到影响。对于需要频繁进行数据操作的应用,可能需要考虑使用其他更高效的数据存储方案。
  • 数据不加密:数据是明文保存的,这意味着敏感信息(如密码、令牌)不应该直接通过 shared_preferences 存储。
  • 缺乏结构化数据支持:只支持基本数据类型(布尔值、整数、字符串等)和字符串列表的存储,不支持复杂的对象或嵌套结构的数据存储。如果需要存储更复杂的数据结构,必须手动序列化和反序列化,增加了代码复杂性。
  • 数据同步性:在 Web 平台或多设备环境下,shared_preferences 不支持自动同步数据。如果用户在多个设备上使用应用,需要手动处理数据同步问题。

七. 总结

shared_preferences 适用于存储小量、非敏感的键值对数据。它的简单性和跨平台支持使其成为许多应用的首选方案,尤其是对于用户偏好设置、应用配置等场景。然而,对于需要处理大量数据、复杂数据结构或敏感信息的应用,shared_preferences 的局限性也不容忽视。

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值