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

使用flutter_secure_storage搭配hydrated_bloc时重启数据丢失问题排查

问题分析与解决方案

你的核心问题是自定义Storage未处理hydrated_bloc与flutter_secure_storage之间的数据格式转换,同时部分方法未实现,导致数据无法正确持久化。以下是具体问题和修正方案:

核心问题点

  1. 序列化/反序列化缺失:hydrated_bloc传递给write的value是状态类转换后的Map<String, dynamic>,但flutter_secure_storage仅支持存储字符串类型,直接写入会导致数据丢失;读取时也需要将字符串解码回Map,才能让hydrated_bloc恢复状态。
  2. 关键方法未实现:delete、clear方法仅做打印,未实际调用flutter_secure_storage的对应逻辑,可能引发后续操作异常。
  3. 返回类型不明确:read方法应显式声明返回Future<dynamic>,避免类型歧义。

修正后的自定义Storage代码

import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';

class CustomHydratedStorage implements Storage {
  final _storage = const FlutterSecureStorage();

  @override
  Future<dynamic> read(String key) async {
    final value = await _storage.read(
      key: key,
      iOptions: const IOSOptions(accessibility: KeychainAccessibility.first_unlock),
      aOptions: const AndroidOptions(
        encryptedSharedPreferences: true,
      ),
    );

    print('Reading $key and got $value');
    // 将读取到的JSON字符串解码为hydrated_bloc需要的Map格式
    return value != null ? jsonDecode(value) : null;
  }

  @override
  Future<void> write(String key, dynamic value) async {
    // 将hydrated_bloc传入的Map序列化为JSON字符串,适配flutter_secure_storage的存储要求
    final jsonValue = jsonEncode(value);
    print('Writing $key = $jsonValue');
    await _storage.write(key: key, value: jsonValue);
  }

  @override
  Future<void> delete(String key) async {
    print('HydratedStorage: delete ($key)');
    await _storage.delete(key: key);
  }

  @override
  Future<void> clear() async {
    print('HydratedStorage: clear');
    await _storage.deleteAll();
  }

  @override
  Future<void> close() async {
    // flutter_secure_storage无close方法,可留空或做必要清理
    print('HydratedStorage: close');
  }
}

额外检查项

  • Android设备兼容性:encryptedSharedPreferences: true要求设备运行Android 6.0(API 23)及以上,且具备硬件加密支持。若测试设备不满足,可暂时关闭该选项验证是否为兼容性问题。
  • 初始化正确性:确保应用启动时正确初始化HydratedBloc:
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      HydratedBloc.storage = CustomHydratedStorage();
      runApp(MyApp());
    }
    
  • 状态类方法实现:确认你的Bloc/Cubit状态类正确实现了toJson()和fromJson()方法,这是hydrated_bloc持久化的基础。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:03:12