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

Flutter Hive热重启后获取数据触发类型转换错误

问题

在Hive Box中存储数据后,首次在FavoritesPage读取完全正常,但热重启应用后进入该页面会抛出类型转换错误。

错误信息

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
抛出以下_CastError错误,发生在构建ValueListenableBuilder<Box>(dirty, state: _ValueListenableBuilderState<Box>#b8b8b)时:
type 'List' is not a subtype of type 'List' in type cast

相关代码

FavoritesPage代码

class _FavoritesPageState extends State<FavoritesPage> {
  @override
  void initState() {
    super.initState();
    //HandleFavorites.deleteAll();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ValueListenableBuilder<Box<List<FavoritesSongs>>>(
        valueListenable: HandleFavorites.getFavoritesSongs().listenable(),
        builder: (context, fav, _) {
          final favorites = fav.values.toList().cast<List<FavoritesSongs>>();
          return favorites.isEmpty
              ? const Center(child: Text('No Sounds Yet'))
              : Column(
                  children: favorites.map((e) => buildContent(e)).toList());
        },
      ),
    );
  }
}

buildContent方法代码

Widget buildContent(List<FavoritesSongs> favoritesSongs) {
  if (favoritesSongs.isEmpty) {
    return const Center(child: Text('Empty'));
  } else {
    return Column(
      children: [
        ListView.builder(
          scrollDirection: Axis.vertical,
          shrinkWrap: true,
          itemCount: favoritesSongs.length,
          itemBuilder: (BuildContext context, int index) {
            final fav = favoritesSongs[index];
            return Text(fav.id);
          },
        ),
        const Divider(
          height: 20,
          thickness: 2,
          color: Colors.black,
        ),
      ],
    );
  }
}

HandleFavorites类代码

class HandleFavorites {
static Box<List<FavoritesSongs>> getFavoritesSongs() =>
      Hive.box<List<FavoritesSongs>>(StaticWords.favorites);
}

Favorites实体类代码

import 'package:hive/hive.dart';

part 'favorites_songs.g.dart';

@HiveType(typeId: 1, adapterName: "FavoritesSongsAdapter")
class FavoritesSongs {
  FavoritesSongs({required this.id, required this.volume});

  @HiveField(0)
  String id;

  @HiveField(1)
  double volume;
}

@HiveType(typeId: 2, adapterName: "FavoritesListAdapter")
class FavoritesList extends HiveObject {
  FavoritesList({required this.listId, required this.listOfSounds});

  @HiveField(0)
  String listId;

  @HiveField(1)
  List<FavoritesSongs> listOfSounds;
}

Hive初始化代码(main.dart)

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Hive.initFlutter();
  Hive.registerAdapter(FavoritesSongsAdapter());
  Hive.openBox<List<FavoritesSongs>>(StaticWords.favorites);
  runApp(const Equable());
}

解决方案

问题根源在于直接用Box<List<FavoritesSongs>>存储列表,Hive无法正确序列化/反序列化嵌套泛型列表,热重启后丢失类型信息导致转换失败。应该使用你定义的FavoritesList类封装列表进行存储:

  1. 修改HandleFavorites类
class HandleFavorites {
static Box<FavoritesList> getFavoritesSongs() =>
      Hive.box<FavoritesList>(StaticWords.favorites);
}
  1. 更新main.dart的Hive初始化逻辑
    注册FavoritesListAdapter并打开对应类型的Box:
Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Hive.initFlutter();
  Hive.registerAdapter(FavoritesSongsAdapter());
  Hive.registerAdapter(FavoritesListAdapter());
  await Hive.openBox<FavoritesList>(StaticWords.favorites);
  runApp(const Equable());
}
  1. 调整FavoritesPage的ValueListenableBuilder
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: ValueListenableBuilder<Box<FavoritesList>>(
      valueListenable: HandleFavorites.getFavoritesSongs().listenable(),
      builder: (context, favBox, _) {
        final favorites = favBox.values.toList();
        return favorites.isEmpty
            ? const Center(child: Text('No Sounds Yet'))
            : Column(
                children: favorites.map((favItem) => buildContent(favItem.listOfSounds)).toList());
      },
    ),
  );
}
  1. 存储数据时使用FavoritesList对象
    添加收藏列表时,创建FavoritesList实例存入Box,而非直接存列表:
void addFavoritesList(String listId, List<FavoritesSongs> songs) {
  final box = HandleFavorites.getFavoritesSongs();
  box.put(listId, FavoritesList(listId: listId, listOfSounds: songs));
}

修改后,Hive会通过生成的FavoritesListAdapter正确处理序列化和反序列化,热重启后不会丢失类型信息,类型转换错误即可解决。

内容的提问来源于stack exchange,提问作者ripouu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:15:51