在这里插入图片描述

在这里插入图片描述

一、什么是SharedPreferences

SharedPreferences是一种轻量级的键值对存储机制,广泛应用于移动应用开发中。它提供了一种简单、高效的方式来存储和读取应用的配置信息、用户偏好设置等少量数据。

1.1 SharedPreferences的特点

特性 说明
存储类型 键值对(Key-Value)
数据类型 基本类型(String、int、double、bool、List)
存储位置 应用私有目录下的XML文件
适用场景 配置信息、用户偏好、少量数据缓存
数据大小 建议不超过100KB

1.2 在Flutter中的实现

Flutter通过shared_preferences包提供了对SharedPreferences的支持。这个包是一个Flutter社区维护的插件,支持Android、iOS、Web等多个平台,包括鸿蒙平台。

二、集成与配置

2.1 添加依赖

在项目的pubspec.yaml文件中添加shared_preferences依赖:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2

然后运行flutter pub get命令获取依赖。

2.2 鸿蒙平台特殊配置

在鸿蒙平台上使用SharedPreferences时,需要确保应用具有正确的权限配置。在module.json5文件中添加以下配置:

{
  "module": {
    "abilities": [],
    "requestPermissions": [
      {
        "name": "ohos.permission.WRITE_USER_DATA",
        "reason": "需要写入用户数据",
        "usedScene": {
          "abilities": ["MainAbility"],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.READ_USER_DATA",
        "reason": "需要读取用户数据",
        "usedScene": {
          "abilities": ["MainAbility"],
          "when": "always"
        }
      }
    ]
  }
}

三、基本操作

3.1 获取SharedPreferences实例

import 'package:shared_preferences/shared_preferences.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences prefs = await SharedPreferences.getInstance();
}

3.2 存储数据

SharedPreferences支持以下数据类型的存储:

// 存储字符串
await prefs.setString('username', '张三');

// 存储整数
await prefs.setInt('age', 25);

// 存储浮点数
await prefs.setDouble('score', 98.5);

// 存储布尔值
await prefs.setBool('isVip', true);

// 存储字符串列表
await prefs.setStringList('tags', ['Flutter', 'HarmonyOS', 'Dart']);

3.3 读取数据

// 读取字符串
String? username = prefs.getString('username');

// 读取整数
int? age = prefs.getInt('age');

// 读取浮点数
double? score = prefs.getDouble('score');

// 读取布尔值
bool? isVip = prefs.getBool('isVip');

// 读取字符串列表
List<String>? tags = prefs.getStringList('tags');

3.4 删除数据

// 删除单个键
await prefs.remove('username');

// 清空所有数据
await prefs.clear();

3.5 检查键是否存在

bool hasKey = prefs.containsKey('username');

3.6 获取所有键

Set<String> keys = prefs.getKeys();

四、实际应用示例

4.1 用户登录状态保存

class AuthService {
  static const String _keyToken = 'auth_token';
  static const String _keyUserId = 'user_id';
  static const String _keyUsername = 'username';

  static Future<void> saveUser(String token, String userId, String username) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString(_keyToken, token);
    await prefs.setString(_keyUserId, userId);
    await prefs.setString(_keyUsername, username);
  }

  static Future<Map<String, String?>> getUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return {
      'token': prefs.getString(_keyToken),
      'userId': prefs.getString(_keyUserId),
      'username': prefs.getString(_keyUsername),
    };
  }

  static Future<void> logout() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.remove(_keyToken);
    await prefs.remove(_keyUserId);
    await prefs.remove(_keyUsername);
  }

  static Future<bool> isLoggedIn() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.containsKey(_keyToken);
  }
}

4.2 应用主题设置

class ThemeService {
  static const String _keyThemeMode = 'theme_mode';
  static const String _keyPrimaryColor = 'primary_color';

  static Future<void> saveTheme(ThemeMode mode, Color color) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString(_keyThemeMode, mode.name);
    await prefs.setInt(_keyPrimaryColor, color.value);
  }

  static Future<ThemeMode> getThemeMode() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? mode = prefs.getString(_keyThemeMode);
    return mode != null ? ThemeMode.values.firstWhere((m) => m.name == mode) : ThemeMode.system;
  }

  static Future<Color> getPrimaryColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    int? colorValue = prefs.getInt(_keyPrimaryColor);
    return colorValue != null ? Color(colorValue) : Colors.blue;
  }
}

4.3 应用设置保存

class AppSettings {
  static const String _keyNotifications = 'notifications';
  static const String _keySoundEnabled = 'sound_enabled';
  static const String _keyAutoUpdate = 'auto_update';
  static const String _keyLanguage = 'language';

  static Future<void> saveSettings({
    required bool notifications,
    required bool soundEnabled,
    required bool autoUpdate,
    required String language,
  }) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setBool(_keyNotifications, notifications);
    await prefs.setBool(_keySoundEnabled, soundEnabled);
    await prefs.setBool(_keyAutoUpdate, autoUpdate);
    await prefs.setString(_keyLanguage, language);
  }

  static Future<Map<String, dynamic>> getSettings() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return {
      'notifications': prefs.getBool(_keyNotifications) ?? true,
      'soundEnabled': prefs.getBool(_keySoundEnabled) ?? true,
      'autoUpdate': prefs.getBool(_keyAutoUpdate) ?? false,
      'language': prefs.getString(_keyLanguage) ?? 'zh',
    };
  }
}

五、SharedPreferences的局限性

5.1 数据类型限制

SharedPreferences只支持基本数据类型,不支持自定义对象的直接存储。如果需要存储复杂对象,需要先将其序列化为JSON字符串。

5.2 数据大小限制

虽然没有严格的大小限制,但由于SharedPreferences使用XML格式存储,数据量过大会导致性能问题。一般建议单个SharedPreferences文件不超过100KB。

5.3 不支持加密

SharedPreferences存储的数据是明文的,不适合存储敏感信息如密码、API Token等。

5.4 异步操作

所有SharedPreferences操作都是异步的,需要使用await关键字。在UI线程中进行大量操作可能会阻塞UI。

六、最佳实践

6.1 使用封装类

将SharedPreferences操作封装到专门的服务类中,提高代码的可维护性和可测试性。

6.2 定义常量键名

使用常量定义键名,避免拼写错误和硬编码。

6.3 处理空值

读取数据时要处理可能的空值情况,提供默认值。

6.4 批量操作

如果需要进行多个操作,可以合并为一个异步块,减少IO操作次数。

6.5 避免频繁读写

对于需要频繁更新的数据,考虑使用内存缓存,定期同步到SharedPreferences。

6.6 使用try-catch

SharedPreferences操作可能会抛出异常,使用try-catch进行错误处理。

七、在鸿蒙平台上的注意事项

7.1 权限配置

确保在module.json5中配置了正确的读写权限。

7.2 数据存储位置

在鸿蒙平台上,SharedPreferences数据存储在应用的沙箱目录中,其他应用无法访问。

7.3 数据迁移

当应用版本升级时,需要考虑数据迁移问题。如果数据结构发生变化,需要编写迁移逻辑。

7.4 性能优化

在鸿蒙平台上,SharedPreferences的性能可能与Android平台略有不同,需要进行实际测试和优化。

八、总结

SharedPreferences是Flutter应用中实现轻量级数据存储的常用方案。它简单易用,适合存储配置信息和用户偏好设置。但由于其局限性,对于复杂数据结构和大量数据,应考虑使用Hive或SQLite等更强大的存储方案。

在鸿蒙平台上使用SharedPreferences时,需要注意权限配置和平台特性,确保应用的稳定性和安全性。

九、参考资料

  1. shared_preferences package
  2. Flutter官方文档 - 数据持久化
  3. HarmonyOS权限管理
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐