为什么这个鸿蒙 Flutter 项目适合用 Riverpod 做状态管理
一个项目适不适合某种状态管理方式,不是看技术热度,而是看它要管理的状态类型够不够复杂。食界探味当前同时有鉴权状态、探索页聚合状态、搜索状态、收藏状态、愿望单状态、AI 会话状态和平台能力状态,这使它天然更适合用 Riverpod 这类能把依赖、生命周期和异步状态一起管理起来的方案。本文结合真实代码,解释为什么这个项目和 Riverpod 是比较匹配的。
适合谁看
-
正在给 Flutter 项目选状态管理方案的人
-
想理解 Riverpod 为什么适合中型内容应用的人
-
已经在项目里看到不少 Provider,但还没理清整体思路的人
问题背景
状态管理方案是否合适,关键看项目里到底有哪些状态:
-
全局状态还是页面状态
-
短生命周期还是长生命周期
-
同步状态还是异步状态
-
纯 UI 状态还是业务状态
如果项目里只有少量页面和简单交互,很多方案都能工作。
但一旦状态类型开始变多,选择就会变得更重要。
项目中的真实场景
食界探味当前和 Riverpod 相关的真实代码主要在:
-
app/lib/main.dart -
app/lib/app.dart -
app/lib/features/auth/providers/auth_provider.dart -
app/lib/features/explore/providers/explore_provider.dart -
app/lib/features/search/providers/search_provider.dart -
app/lib/features/collection/providers/collection_provider.dart -
app/lib/features/wish_box/providers/wish_provider.dart -
app/lib/core/ai/ai_explore_coordinator.dart
从这些文件就能看出,这个项目的状态不是集中在一个模块里,而是分布在多个业务域中。
而且它还不是一个普通 Flutter 应用,因为状态最终还要承接来自 HarmonyOS 的系统入口和平台事件,例如:
-
app/lib/core/platform/intent_navigation_channel.dart -
app/lib/core/platform/anti_peep_protection_channel.dart -
app/ohos/entry/src/main/ets/entryability/EntryAbility.ets
核心实现
这篇如果只说“Provider 很多,所以适合 Riverpod”,其实还是不够。
真正的判断应该回到两个问题:
-
项目里到底有哪些不同类型的状态
-
这些状态是不是还要和 HarmonyOS 的系统入口、平台回调一起协作
一、这个项目里有很多“异步业务状态”,而且分布在不同业务域
例如:
-
鉴权登录状态
-
探索首页数据加载状态
-
搜索请求状态
-
收藏和已吃过状态
-
愿望单提交状态
-
AI 会话状态
这些状态都不是简单的本地布尔值,而是带有:
-
加载中
-
成功
-
失败
-
刷新
等阶段变化。
Riverpod 在这里真正的价值,不是“能存值”,而是能比较自然地表达:
-
一个状态是不是异步状态
-
这个状态属于哪个业务域
-
谁依赖谁
-
生命周期要不要回收
例如当前项目里就已经有比较清楚的分域:
-
authProvider管登录态 -
exploreProvider管首页聚合数据 -
searchProvider管搜索状态和翻页 -
wishHomeProvider、wishSubmitProvider管许愿箱首页与表单提交流程
这种分法和 Riverpod 的思路是匹配的。
二、状态天然按功能分散,而不是集中成一个超级 Store
当前项目的 Provider 分布方式很清楚:
-
每个 feature 有自己的 providers
-
AI 在
core/ai -
全局路由和配置在
app.dart、core/config
这和 Riverpod“按依赖组织,而不是按全局仓库组织”的思路很匹配。
换句话说,当前项目不是那种“所有状态都想塞进一个大对象”的结构,而是:
-
每个 feature 管自己的状态
-
repository 通过 Provider 注入
-
页面只 watch 自己真正关心的状态切片
这点在鸿蒙 Flutter 项目里尤其重要。
因为系统入口、平台事件、AI 会话这些状态如果也被硬塞进同一个超级 Store,后面会很难控制边界。
三、很多状态本身带生命周期,而鸿蒙场景会把生命周期问题放大
例如:
-
搜索结果离开页面后可以释放
-
AI 会话页面离开后可以回收
-
提交表单的临时状态不需要全局常驻
项目里已经大量使用:
-
StateNotifierProvider.autoDispose
这说明它不只是想“保存状态”,而是也在关心状态何时销毁。
而到了鸿蒙项目里,这件事会更关键。
因为有些状态并不是只受 Flutter 页面生命周期影响,还会受系统入口和原生事件影响,例如:
-
Intents Kit 可能在应用冷启动时带进
pageId -
防窥状态可能在页面已经显示时由原生侧异步推回
-
语音识别和 TTS 会把页面状态从 idle 拉到 listening / speaking
如果状态层本身没有分域、没有生命周期意识,Flutter 侧就很难优雅接住这些平台侧回调。
四、Riverpod 更适合把依赖显式写出来,而不是靠隐式单例串项目
像 routerProvider、authProvider、aiExploreCoordinatorProvider 这类对象,都更适合通过 Provider 显式暴露依赖关系,而不是通过隐式单例到处拿。
这对鸿蒙项目还有一个额外好处:
-
Flutter 侧路由、业务状态、平台边界对象可以保持清楚分层
例如:
-
routerProvider只管路由对象 -
authProvider只管登录态 -
IntentNavigationChannel负责平台入口转路由 -
AntiPeepProtectionChannel负责平台事件转页面状态
Riverpod 并不会替你处理所有平台问题,但它能让你把“谁管什么”写得更清楚。
五、这个项目适合 Riverpod,还有一个常被忽略的原因:Flutter 状态要承接 HarmonyOS 平台回调
很多 Flutter 项目只讨论页面状态;但食界探味不是这样。
它至少已经有三类明显来自平台侧的输入:
-
EntryAbility和InsightIntentExecutorImpl带进来的系统直达参数 -
IntentNavigationChannel在 Flutter 侧消费的 pending navigation -
AntiPeepProtectionChannel推回来的可见性事件
这意味着 Flutter 状态层不能只想着:
-
页面按钮点了之后怎么改状态
还得能接住:
-
系统从外面打进来的状态变化
Riverpod 在这里的适配点就在于:
-
业务状态仍然按 feature 管
-
路由和平台边界可以单独暴露
-
页面可以只 watch 自己需要的状态,而不用被整套平台逻辑污染
关键代码位置
-
app/lib/main.dart -
app/lib/app.dart -
app/lib/features/auth/providers/auth_provider.dart -
app/lib/features/explore/providers/explore_provider.dart -
app/lib/features/search/providers/search_provider.dart -
app/lib/features/collection/providers/collection_provider.dart -
app/lib/features/wish_box/providers/wish_provider.dart -
app/lib/core/ai/ai_explore_coordinator.dart
鸿蒙侧实现
这一篇虽然重点在 Flutter 状态层,但它和鸿蒙其实有非常直接的关系。
对 HarmonyOS Flutter 项目来说,Flutter 侧状态管理越清晰,越容易承接来自:
-
Intent 导航
-
语音识别
-
防窥事件
这些平台侧回调。
当前项目里最值得注意的是:
-
原生层并没有直接去改 Flutter 页面
-
它只是把入口参数或事件推到边界层
-
真正把这些变化吸收到页面里的,仍然是 Flutter 状态组织方式
也就是说,Riverpod 在这里不是离鸿蒙很远,反而是在帮 Flutter 层接住鸿蒙。
Flutter 侧实现
当前项目已经体现出几条比较典型的 Riverpod 用法:
-
全局用
ProviderScope -
功能模块用
StateNotifierProvider -
临时状态优先
autoDispose -
路由和服务也可以通过 Provider 暴露
这是一种比较稳的中型应用组织方式。
如果再结合鸿蒙相关代码一起看,会更清楚:
-
ProviderScope负责把状态系统立起来 -
GoRouter通过 Provider 暴露 -
平台边界对象负责接住原生输入
-
feature provider 负责把这些输入变成页面真正可消费的状态
常见坑
-
所有状态都放进一个超大 Provider
-
页面临时状态不回收,导致内存和逻辑膨胀
-
把服务对象、路由对象、业务状态对象混在一起
-
只用 Riverpod 保存值,却不利用它的依赖管理能力
-
平台回调直接改页面局部状态,没有经过统一状态层
-
为了接鸿蒙能力,把原生事件逻辑直接散落到多个页面里
可复用模板
final searchProvider =
StateNotifierProvider<SearchNotifier, SearchState>((ref) {
return SearchNotifier(ref);
});
业务状态按 feature 拆
平台边界单独收在 core/platform
路由对象单独暴露
系统入口和平台事件最终回到状态层消费
本篇总结
-
食界探味适合 Riverpod,不是因为它流行,而是因为项目状态类型本身很多,而且来源不只在页面内部
-
Riverpod 在这里真正解决的是依赖显式化、状态分域、生命周期管理,以及对 HarmonyOS 平台输入的承接
-
对这种带 AI、带平台能力、带系统直达入口的鸿蒙 Flutter 项目来说,这个选择是合理的
更多推荐




所有评论(0)