桑拿控制器项目持久化层笔记

本文内容包含:结构说明、使用方法、踩坑点、当前项目采用的方案(GetStorage + Hive)、目录结构、初始化方法、注意事项等。


📘 桑拿控制器项目持久化层(Storage Layer)技术笔记

本笔记用于记录 Sauna Controller 项目中"本地存储(持久化层)"的设计方式、用法、文件结构和常见错误,方便后续开发、维护和排查问题。


⭐ 1. 持久化层作用

项目中所有需要"应用重启后仍然保留"的数据都要放在持久层,例如:

✔ 彩灯状态(开关、颜色、亮度、角度、模式)

✔ 卡路里历史记录(最多 15 条)

✔ 用户设置项(未来扩展)

✔ 运行历史值(温杯、次数等)

为了方便使用和提高扩展性,项目采用了 两种本地存储方式


⭐ 2. 项目中使用的两种存储方式

A. GetStorage → 用于轻量级 Key--Value 保存

适合存:

  • 彩灯开关
  • 当前色号 index
  • 当前亮度 level
  • 色环角度 angle
  • 是否渐变模式 gradualMode
  • 一些布尔值、整型、小配置项

特点:

特点 说明
非常轻量 无需模型类,直接 key-value
没有效率问题 读写只操作内存,写入自动持久化
使用简单 .write().read()

示例:

dart 复制代码
box.write("color_isOn", true);
bool on = box.read("color_isOn");

B. Hive(Hive + hive_flutter)→ 用于结构化数据持久化

适合存:

  • 卡路里历史记录(有日期、有卡路里值)

特点:

特点 说明
高性能 NoSQL 数据库 Flutter 最快的本地库之一
Dart 强类型 需要 Model + Adapter
适合复杂对象 可存 List、对象、结构体
本项目用于存 CalorieRecord 历史卡路里记录

结构模型:

dart 复制代码
@HiveType(typeId: 1)
class CalorieRecord extends HiveObject {
  @HiveField(0) int calories;
  @HiveField(1) int durationMin;
  @HiveField(2) int temperature;
  @HiveField(3) DateTime time;
}

编译后会生成:

复制代码
calorie_record.g.dart

⭐ 3. 持久化目录结构(项目现状)

复制代码
lib/
 ├─ models/
 │   ├─ calorie_record.dart        ← Hive 模型(包含 adapter)
 │   └─ calorie_record.g.dart      ← 自动生成的适配器文件
 │
 ├─ services/
 │   ├─ storage/
 │   │     └─ storage_service.dart ← 持久化统一入口(本层核心)
 │   └─ ble/...
 │
 ├─ main.dart                      ← 初始化 Storage
 └─ ...

⭐ 4. 全局持久化入口:AppStorage()

整个项目只需要 一个统一的存储服务类,用于管理所有存储的读写。

文件:

复制代码
lib/services/storage/storage_service.dart

核心职责:

  1. 初始化 GetStorage(轻量 KV)
  2. 初始化 Hive(结构化数据)
  3. 注册 Hive Adapter
  4. 打开 Hive box(calorie_history)
  5. 提供所有持久化的 Getter / Setter

⭐ 5. AppStorage 初始化流程

⚠ 必须在 main.dart 调用,否则 Hive / GetStorage 都不能使用。

main.dart ⬇(当前项目已更新为正确写法)

dart 复制代码
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 全局持久化初始化
  await AppStorage().init();

  runApp(const SaunaApp());
}

⭐ 6. AppStorage 内部实现重点(总结版)

✔ 初始化 GetStorage

dart 复制代码
await GetStorage.init();

✔ 初始化 Hive(注意:用 Hive.initFlutter,不用 path_provider)

dart 复制代码
await Hive.initFlutter();

✔ 注册 Adapter

dart 复制代码
Hive.registerAdapter(CalorieRecordAdapter());

✔ 打开 box

dart 复制代码
historyBox = await Hive.openBox<CalorieRecord>("calorie_history");

✔ GetStorage 中的 Key--Value 访问

dart 复制代码
bool get colorIsOn => box.read("color_isOn") ?? false;
set colorIsOn(bool v) => box.write("color_isOn", v);

✔ Hive 中的历史记录保存(只有 15 条)

dart 复制代码
void addCalorieRecord(CalorieRecord r) {
  if (historyBox.length >= 15) {
    historyBox.deleteAt(0);
  }
  historyBox.add(r);
}

⭐ 7. 常见错误 & 排查指南(最重要)

❌ 1. 忘记在 main.dart 初始化

症状:Hive 报错:box is null or not opened

解决:确认 main.dart 有:

dart 复制代码
await AppStorage().init();

❌ 2. 使用 Hive.init 而不是 Hive.initFlutter

症状:Web 端无法运行 / Android 运行但警告

解决:

dart 复制代码
await Hive.initFlutter();

❌ 3. calorie_record.g.dart 未生成

症状:找不到 CalorieRecordAdapter

解决:

终端运行:

复制代码
flutter packages pub run build_runner build --delete-conflicting-outputs

❌ 4. storage_service.dart 路径不一致

症状:import 报错

正确目录:

复制代码
lib/services/storage/storage_service.dart

❌ 5. Hive Box 打开失败

原因通常是:

  • 适配器未注册
  • typeId 冲突
  • g.dart 未生成

⭐ 8. 彩灯模块持久化字段(当前项目)

字段 说明 存储方式
color_isOn 灯开关状态 GetStorage
color_index 颜色序号 1~12 GetStorage
color_brightness 亮度等级 1~4 GetStorage
color_angle 色环角度 GetStorage
color_gradual 是否渐变模式 GetStorage

(轻量,适合 GetStorage)


⭐ 9. 卡路里模块持久化字段(当前项目)

字段 说明 存储方式
calorie_history 卡路里历史记录(最多 15 条) Hive

(结构化,适合 Hive)


⭐ 10. 什么时候使用哪种存储?

数据类型 推荐存储
简单状态(bool、int、String) GetStorage
结构化对象 Hive
历史记录、列表 Hive
UI 设置项 GetStorage
大体积数据 Hive

⭐ 总结(一句话)

GetStorage 负责简单状态(KV),Hive 负责结构化历史记录(对象)。
整个项目所有持久化入口都在 AppStorage(),main.dart 启动时必须 init() 一次。

相关推荐
Lv117700819 小时前
Visual Studio 中的字符串
ide·笔记·c#·visual studio
Lv117700819 小时前
Visual Studio中的 var 和 dynamic
ide·笔记·c#·visual studio
代码游侠19 小时前
学习笔记——线程
linux·运维·开发语言·笔记·学习·算法
QT 小鲜肉20 小时前
【Linux命令大全】001.文件管理之chgrp命令(实操篇)
android·linux·运维·笔记
摇滚侠20 小时前
Redis 零基础到进阶,Redis 持久化,RDB,AOF,RDB AOF 混合,笔记 28-46
数据库·redis·笔记
yenggd20 小时前
锐捷gre over ipsec结合ospf配置案例
运维·网络·笔记
阿蒙Amon20 小时前
JavaScript学习笔记:13.Promise
javascript·笔记·学习
找方案20 小时前
hello-agents 学习笔记:从概念到落地,初识智能体的奇妙世界
人工智能·笔记·学习·大模型
Lv117700820 小时前
Visual Studio 中的 ArrayList数组 和 List数组
数据结构·笔记·c#·list·visual studio
狮智先生20 小时前
【学习笔记】利用blender生成的mesh模型(ply格式)并不是水密的
笔记·学习·blender