You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:50:16