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
相关产品推荐
相关产品推荐

