GetStorage 是 GetX 提供的一个轻量级键值存储工具,类似于 Flutter 中的 SharedPreferences,但相比之下更加简单高效。它支持同步数据读写,并且可以直接用于小型数据持久化存储。
1. GetStorage 的特点
- 轻量级:核心库只有几 KB,非常适合处理少量数据存储需求。
- 性能高:基于内存缓存机制,数据在内存中操作,读写速度快。
- 无上下文依赖:不需要 BuildContext,可以在任意位置使用。
- 实时监听:支持对数据变化的监听。
- 数据持久化:存储的数据会自动持久化到设备的本地存储中(基于 JSON 格式)。
- 初始化简单:无需复杂的配置,开箱即用。
2. GetStorage 的初始化
在使用 GetStorage 之前,需要先进行初始化。初始化时会创建一个默认的存储容器。
import 'package:flutter/material.dart';
import 'package:get_storage/get_storage.dart';
void main() async {
await GetStorage.init(); // 初始化 GetStorage
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
⚠️ 注意:GetStorage.init() 是异步操作,因此需要在 main 函数中使用 await,确保初始化完成后再运行应用。
3. GetStorage 的基本用法
3.1 创建存储实例
GetStorage 默认会提供一个全局实例。
final box = GetStorage(); // 获取默认存储实例
如果需要多个存储容器,也可以自定义存储实例。
final userBox = GetStorage('UserBox'); // 创建名为 UserBox 的存储实例
3.2 数据存储
通过 write 方法将数据存储到本地。
box.write('username', 'JohnDoe'); // 存储字符串
box.write('isLoggedIn', true); // 存储布尔值
box.write('userAge', 25); // 存储数字
box.write('preferences', {'theme': 'dark', 'fontSize': 16}); // 存储对象
除了 write 方法以外,还有 save 方法和 cache 方法。
3.2.1 save的作用
- save 是对 write 的封装,用于保证数据立即且持久地写入磁盘。
- 每次调用 save 时,会直接触发磁盘操作,确保数据可以在应用重启后仍然存在。
- 本质上,save 等价于 write,但语义上更强调持久化存储。
实现逻辑(伪代码):
Future<void> save(String key, dynamic value) async {
await write(key, value); // 使用底层 write 方法实现存储
}
使用场景:
final storage = GetStorage();
storage.save('username', 'JohnDoe'); // 等价于 storage.write('username', 'JohnDoe')
3.2.2 cache的作用
- cache 是对 write 的增强,额外引入了内存缓存机制。
- 当调用 cache 时:
- 数据首先写入内存缓存(内存中的快速临时存储)。
- 随后以异步方式写入磁盘存储。
- 这种机制提升了写入性能,特别适合频繁读写的数据。
实现逻辑(伪代码):
Future<void> cache(String key, dynamic value) async {
memoryCache[key] = value; // 将数据存入内存缓存
write(key, value); // 异步写入磁盘(调用底层 write 方法)
}
使用场景:
final storage = GetStorage();
storage.cache('username', 'JohnDoe'); // 优化性能的存储方式
⚠️ 注意:尽管 cache 主要强调内存缓存的优化,它最终还是会将数据异步写入磁盘,因此应用重启后仍然可以通过 read 方法读取到这些数据。
final storage = GetStorage();
// 重启后再次读取
print(storage.read('username')); // 输出: JohnDoe
3.3 数据读取
通过 read 方法读取数据。
String username = box.read('username') ?? 'Guest';
bool isLoggedIn = box.read('isLoggedIn') ?? false;
Map<String, dynamic> preferences = box.read('preferences') ?? {};
3.4 数据删除
通过 remove 方法删除某个键值对。
box.remove('username'); // 删除键为 'username' 的数据
删除所有数据。
box.erase(); // 清空存储容器
4. GetStorage 的存储位置
在 GetStorage 中,保存的数据存储在设备的文件系统中,其具体位置依赖于运行的操作系统和平台。
4.1 Android 平台
在 Android 平台上,GetStorage 使用了应用的内部存储目录,数据通常存储在以下位置:
/data/data/<your_app_package_name>/files/get_storage/
特点:
- 私有存储: 该路径属于应用的沙箱环境,其他应用无法访问这些文件。
- 安全性: 数据默认只对当前应用可见,不需要额外权限。
- 删除情况: 当用户卸载应用时,此目录会被系统自动清理。
4.2 iOS 平台
在 iOS 平台上,GetStorage 数据存储在应用的沙盒目录下:
<your_app_sandbox>/Documents/get_storage/
特点:
- 沙盒机制: 数据被存储在 Documents 文件夹下,该文件夹对当前应用是私有的。
- iCloud 同步: 由于存储在 Documents 文件夹,默认可能会被 iCloud 自动备份(如果启用了备份的话)。
- 删除情况: 应用被卸载时,此目录会被系统清理。
5. GetStorage 的进阶功能
5.1 数据监听
GetStorage 支持对指定键的变化进行监听。每当数据发生变化时,回调函数会被触发。
box.listen(() {
print('数据发生变化:${box.read('username')}');
});
// 或监听特定键
box.listenKey('username', (value) {
print('用户名更新为:$value');
});
5.2 数据同步
GetStorage 的所有操作都是同步的,存储操作立即生效,因此不需要等待异步操作完成。
5.3 自定义储存位置
默认情况下,GetStorage 会在设备的默认存储路径下创建一个 JSON 文件。如果需要自定义存储路径,可以在初始化时指定。
await GetStorage.init('UserBox', 'your/custom/path');
6. 使用场景
6.1 保存用户登录状态
final box = GetStorage();
// 保存登录状态
void login() {
box.write('isLoggedIn', true);
}
// 检查用户是否已登录
bool checkLoginStatus() {
return box.read('isLoggedIn') ?? false;
}
6.2 实现主题切换并保存用户选择
final box = GetStorage();
// 切换主题并保存
void toggleTheme() {
bool isDarkMode = box.read('isDarkMode') ?? false;
box.write('isDarkMode', !isDarkMode);
Get.changeTheme(isDarkMode ? ThemeData.light() : ThemeData.dark());
}
// 初始化时加载用户选择的主题
void loadTheme() {
bool isDarkMode = box.read('isDarkMode') ?? false;
Get.changeTheme(isDarkMode ? ThemeData.dark() : ThemeData.light());
}
6.3 保存用户设置和偏好
final box = GetStorage();
// 保存用户偏好
void savePreferences() {
box.write('preferences', {
'theme': 'dark',
'fontSize': 16,
'notificationsEnabled': true,
});
}
// 读取用户偏好
Map<String, dynamic> loadPreferences() {
return box.read('preferences') ?? {};
}
6.4 本地缓存接口数据
一般情况下,可以通过 GetStorage 缓存接口数据,减少重复请求。
Future<Map<String, dynamic>> fetchData() async {
final cachedData = box.read('apiData');
if (cachedData != null) {
return cachedData; // 返回缓存数据
}
// 模拟从 API 获取数据
final apiData = {'id': 1, 'name': 'GetX'};
box.write('apiData', apiData); // 缓存数据
return apiData;
}
7. 与其他常用的存储工具的对比
| 特性 | GetStorage | SharedPreferences | Hive |
|---|---|---|---|
| 异步支持 | 同步读写 | 异步 | 异步 |
| 数据格式 | JSON 格式 | 键值对 | 自定义二进制格式 |
| 性能 | 高性能 | 中等 | 高性能 |
| 监听支持 | 支持 | 不支持 | 支持 |
| 自定义存储位置 | 支持 | 不支持 | 支持 |
| 使用场景 | 小型存储 | 小型存储 | 大量结构化数据存储 |
8. 注意事项
-
非大型存储解决方案:GetStorage 适合用于小型数据存储(如用户偏好、状态标志等)。如果需要存储大量或复杂结构的数据,建议使用 Hive 或 SQLite。
-
默认存储位置:GetStorage 默认会将数据存储在应用的私有存储路径中,删除应用时会一并清除。
-
加密存储:GetStorage 本身不提供加密功能。如果需要安全存储敏感数据,建议结合加密库(如 encrypt)使用。
9. 总结
GetStorage 是一个轻量级、快速、易用的存储工具,特别适合以下场景:
- 存储用户偏好和设置(如主题、语言选择)。
- 缓存小型接口数据。
- 保存应用状态(如登录状态、Token 等)。
- 实现数据变化监听。
通过简单的 API 和高效的性能,GetStorage 成为小型数据存储的优秀选择,与 GetX 框架的其他模块无缝集成,为使用者带来了极大的便利。