Hive中如何读写自定义嵌套对象?缓存遇类型转换问题求解
解决Hive缓存嵌套动态列表的类型丢失问题
问题根源
直接存储List<Map<String, dynamic>>时,Hive序列化会将其转为_InternalLinkedHashMap<dynamic, dynamic>,重启后类型信息丢失,导致强制类型转换失败。以下是几个无需手动编写大量适配器的解决方案:
方案1:JSON字符串序列化(快速简便)
把整个列表序列化为JSON字符串存储,取出时再反序列化并转换类型,绕开Hive的动态类型问题。
存储代码
import 'dart:convert'; import 'package:hive/hive.dart'; // 假设apiResponse是你从接口拿到的List<Map<String, dynamic>> final jsonStr = jsonEncode(apiResponse); await Hive.box('api_cache').put('list_data', jsonStr);
读取代码
import 'dart:convert'; import 'package:hive/hive.dart'; final jsonStr = Hive.box('api_cache').get('list_data'); if (jsonStr != null) { // 先转成动态列表,再逐个转换为Map<String, dynamic> final rawList = jsonDecode(jsonStr) as List<dynamic>; final List<Map<String, dynamic>> dataList = rawList.map((item) => item.cast<String, dynamic>()).toList(); // 现在dataList就是你需要的类型,可直接用于解析对象 }
方案2:用代码生成自动生成Hive适配器
如果需要类型安全,不用手动写嵌套对象的适配器,借助hive_generator自动生成:
1. 添加依赖
在pubspec.yaml中加入:
dependencies: hive: ^2.2.3 hive_flutter: ^1.1.0 dev_dependencies: hive_generator: ^1.1.5 build_runner: ^2.1.7
2. 定义带注解的实体类
给主对象和嵌套对象都加上@HiveType和@HiveField注解:
import 'package:hive/hive.dart'; part 'user.g.dart'; @HiveType(typeId: 0) class User { @HiveField(0) final String name; @HiveField(1) final Address address; // 嵌套对象 User(this.name, this.address); } @HiveType(typeId: 1) class Address { @HiveField(0) final String street; @HiveField(1) final String city; Address(this.street, this.city); }
3. 生成适配器
在终端运行命令:
flutter pub run build_runner build
4. 注册并使用
void main() async { await Hive.initFlutter(); // 自动生成的适配器会以类名+Adapter命名 Hive.registerAdapter(UserAdapter()); Hive.registerAdapter(AddressAdapter()); await Hive.openBox('api_cache'); runApp(MyApp()); } // 存储 final user = User('张三', Address('长安街', '北京')); await Hive.box('api_cache').put('user', user); // 读取 final user = Hive.box('api_cache').get('user') as User;
方案3:Freezed+Hive简化嵌套对象处理
用Freezed生成不可变对象,同时自动处理序列化逻辑,进一步减少样板代码:
1. 添加依赖
dependencies: hive: ^2.2.3 freezed_annotation: ^2.2.0 hive_flutter: ^1.1.0 dev_dependencies: build_runner: ^2.1.7 freezed: ^2.3.2 hive_generator: ^1.1.5
2. 定义Freezed实体类
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hive/hive.dart'; part 'user.freezed.dart'; part 'user.g.dart'; @HiveType(typeId: 0) @freezed class User with _$User { const factory User({ @HiveField(0) required String name, @HiveField(1) required Address address, }) = _User; factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); } @HiveType(typeId: 1) @freezed class Address with _$Address { const factory Address({ @HiveField(0) required String street, @HiveField(1) required String city, }) = _Address; factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json); }
3. 生成代码并使用
运行flutter pub run build_runner build生成适配器和序列化代码,之后注册适配器即可正常存储嵌套对象。
内容的提问来源于stack exchange,提问作者hrishikesh rajwade
相关产品推荐
相关产品推荐

