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

Flutter中HydratedBloc与Freezed结合使用及序列化报错求助

Flutter中HydratedBloc与Freezed结合的正确实现方式

你的代码报错核心原因是手动重复定义了fromJson和toJson方法——Freezed结合json_serializable会自动为状态类生成这两个序列化方法,手动实现会和生成的代码冲突。以下是完整的正确实现方案:

1. 依赖配置(pubspec.yaml)

确保你的项目依赖包含以下内容:

dependencies:
  flutter:
    sdk: flutter
  flutter_bloc: ^8.1.3
  hydrated_bloc: ^9.1.3
  freezed_annotation: ^2.4.1
  json_annotation: ^4.8.1
  hive_flutter: ^1.1.0 # HydratedBloc依赖Hive做持久化

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.6
  freezed: ^2.4.5
  json_serializable: ^6.7.1

2. 正确的CounterState实现

不需要手动写toJson,仅声明fromJson工厂方法即可,Freezed会自动生成序列化相关代码:

part of 'counter_cubit.dart';
part 'counter_state.freezed.dart';
part 'counter_state.g.dart'; // json_serializable生成的文件

@freezed
class CounterState with _$CounterState {
  const factory CounterState({
    required int number,
  }) = _CounterState;

  // 空状态构造函数
  factory CounterState.empty() => const CounterState(number: 0);

  // 由json_serializable自动生成实现的工厂方法
  factory CounterState.fromJson(Map<String, dynamic> json) =>
      _$CounterStateFromJson(json);
}

3. CounterCubit的实现(结合HydratedCubit)

HydratedCubit需要实现状态的持久化逻辑,直接调用Freezed生成的序列化方法即可:

import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'counter_cubit.freezed.dart';
part 'counter_state.dart';

class CounterCubit extends HydratedCubit<CounterState> {
  CounterCubit() : super(CounterState.empty());

  void increment() => emit(state.copyWith(number: state.number + 1));
  void decrement() => emit(state.copyWith(number: state.number - 1));

  @override
  CounterState? fromJson(Map<String, dynamic> json) {
    return CounterState.fromJson(json);
  }

  @override
  Map<String, dynamic>? toJson(CounterState state) {
    return state.toJson();
  }
}

4. 初始化HydratedBloc存储

在main.dart中完成HydratedBloc的初始化,确保状态可以持久化:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';

import 'counter_cubit.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  HydratedBloc.storage = await HydratedStorage.build(
    storageDirectory: await getApplicationDocumentsDirectory(),
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => CounterCubit(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: const Text('HydratedBloc + Freezed Demo')),
          body: Center(
            child: BlocBuilder<CounterCubit, CounterState>(
              builder: (context, state) {
                return Text(
                  'Count: ${state.number}',
                  style: const TextStyle(fontSize: 24),
                );
              },
            ),
          ),
          floatingActionButton: Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              FloatingActionButton(
                onPressed: () => context.read<CounterCubit>().increment(),
                child: const Icon(Icons.add),
              ),
              const SizedBox(height: 10),
              FloatingActionButton(
                onPressed: () => context.read<CounterCubit>().decrement(),
                child: const Icon(Icons.remove),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

关键注意事项

  • 执行代码生成命令:写完代码后运行flutter pub run build_runner build,生成Freezed和json_serializable的相关文件。
  • 不要手动重写toJson:Freezed生成的_$CounterStateToJson方法会自动处理序列化,手动实现会引发冲突,这是你之前报错的核心原因。
  • 必须初始化HydratedStorage:否则状态无法持久化,重启应用后会丢失数据。

内容的提问来源于stack exchange,提问作者Alper Efe Sahin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:05:20