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

如何使用Riverpod完成SharedPreferences依赖注入

Riverpod 中实例化 SharedPreferences 的最佳实践

你的问题核心是 SharedPreferences.getInstance() 返回的是 Future<SharedPreferences>,而你直接将异步返回的 Future 注入给了需要同步获取实例的数据源,导致类型不匹配。推荐以下两种方案,优先选择第一种预初始化方案。

方案一:启动前预初始化(首推)

SharedPreferences 初始化速度极快,提前在应用启动前完成初始化,后续所有依赖都可以同步获取实例,无需处理异步状态。

步骤1:修改 main 函数完成预初始化

void main() async {
  // 确保 Flutter 插件初始化完成,否则无法调用 SharedPreferences 原生方法
  WidgetsFlutterBinding.ensureInitialized();
  // 同步等待 SharedPreferences 实例初始化完成
  final sharedPreferences = await SharedPreferences.getInstance();

  runApp(
    ProviderScope(
      overrides: [
        // 将初始化完成的实例覆盖注入到 provider 中
        sharedPreferencesProvider.overrideWithValue(sharedPreferences),
      ],
      child: const MyApp(),
    ),
  );
}

步骤2:修改 sharedPreferencesProvider 定义

// 声明返回 SharedPreferences 实例,默认实现抛出异常避免未覆盖的情况被误用
final sharedPreferencesProvider = Provider<SharedPreferences>((ref) {
  throw UnimplementedError('sharedPreferencesProvider 需在启动时通过 overrideWithValue 注入实例');
});

修改后你原本的其他 provider 不需要做任何调整,直接 ref.watch(sharedPreferencesProvider) 就可以拿到可用的 SharedPreferences 实例。

方案二:异步加载适配

如果不想阻塞应用启动,也可以将整条依赖链适配为异步处理:

步骤1:将 sharedPreferencesProvider 改为 FutureProvider

final sharedPreferencesProvider = FutureProvider<SharedPreferences>((ref) async {
  return await SharedPreferences.getInstance();
});

步骤2:调整依赖的 provider 适配异步

所有依赖 sharedPreferencesProvider 的 provider 都需要改为异步实现,例如本地数据源 provider:

final _localDataSourceProvider = FutureProvider<ItemLocalDataSource>((ref) async {
  // 等待 SharedPreferences 实例初始化完成
  final prefs = await ref.watch(sharedPreferencesProvider.future);
  return ItemLocalDataSourceImpl(sharedPreferences: prefs);
});

后续依赖该数据源的 repository、use case、状态管理器都需要对应处理 AsyncValue 的 loading、error 状态,适合初始化耗时较长的依赖,不推荐给 SharedPreferences 使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 03:54:04