把一套完整的 Flutter 应用往 OpenHarmony 设备上搬的时候,你会发现一件挺微妙的事:页面渲染能跑起来,动画也不卡,网络请求也能通,但一旦页面数量多起来、状态开始交叉,之前用 setState 加 InheritedWidget 堆出来的那套代码,会变得极其难受。我是在做鸿蒙 Next 适配的第三周遇到这个瓶颈的,也就是在那时候开始认真研究 refena 这个 Flutter 三方库。
refena 是一个面向 Flutter 的响应式状态管理框架,官方定位是“新一代”,核心卖点是编译期代码生成、类型安全、自带依赖容器和可测试性。这篇文章不是什么官方文档的翻译,而是我在 OpenHarmony 真机上把 refena 用进项目的完整记录:包括它到底解决了什么问题、接入时依赖怎么处理、和以前用 setState 写法在真机上的表现对比,以及适配过程中踩到的一些坑。如果你正在做 Flutter for OpenHarmony 的适配,或者只是在纠结状态管理选型,这篇应该能给你一些参考。
1. 当 Flutter 项目开始适配鸿蒙,状态管理为什么成了第一个瓶颈
1.1 一个实际的适配场景:页面交互正常,状态层却拖了后腿
先说一下我手上的项目背景:一套中等规模的 Flutter 应用,大概二十多个业务页面,包含登录态、订单状态、消息未读数、主题切换这类跨页面共享状态。开发初期跑 Android 和 iOS 都很正常,直到某天我把工程切到 OpenHarmony 的 Flutter SDK 分支,编译过了、首页能打开、列表能滑动,但我心里很清楚,真正的麻烦还没来。
麻烦果然来了。在鸿蒙真机上测试时,登录成功了,个人中心页却没有同步显示用户信息;消息未读数在 A 页面变了,B 页面的角标还是旧数据。问题倒不是 Flutter 渲染层在 OpenHarmony 上出了问题,而是我原来那套状态管理方式本身太脆弱了:setState 只能管到自己所在的 State 对象,跨页面数据全靠构造函数往下传,传到第三层就没人愿意继续传了,最后变成全局单例一把梭。
全局单例在 Android 上勉强能跑,但在鸿蒙这种多任务切换更频繁、页面生命周期更容易被回收的环境里,全局变量的状态恢复就经常对不上。某个页面被系统回收后重建,单例里存的对象还在,但页面监听的部分已经丢了,表现出来就是“数据有,但 UI 不刷新”。
1.2 流行方案在 OpenHarmony 上的共性软肋
遇到这种问题,第一反应是换一个成熟的状态管理库。我花了几天时间把 Flutter 生态里常见的几个方案都在 OpenHarmony 环境里过了一遍,结论是:它们大多能用,但都有一些让你不舒服的地方。
Provider 是最轻量的,纯 Dart 实现,在鸿蒙上适配基本无障碍。但 Provider 本质还是依赖 InheritedWidget,状态一多、嵌套一深,context.watch 的粒度很难掌控,稍微不注意就会导致整棵子树重建。项目到后期,Provider 反而成了性能隐患。
Riverpod 的功能和类型安全都不错,但它的代码生成、编译期检查在 OpenHarmony 的构建链路里要多花不少精力去调。尤其是团队里如果有人不熟悉 build_runner,出现生成文件冲突时很容易卡住整个 CI。
Bloc 的架构很清晰,但样板代码太多,一个简单的计数器都要写事件、状态、Bloc、页面四个文件。对于鸿蒙这种新增平台、需要快速验证功能的阶段,Bloc 的迭代效率有点跟不上。
GetX 倒是用起来爽,但太重了,而且全局单例体系和路由绑定太深,在鸿蒙的多窗口场景下表现并不稳定。网上对 GetX 的批评主要集中在“不可测试”“依赖隐式”,这些毛病在鸿蒙适配时会放大。
1.3 refena 的定位:为什么偏偏是它被讨论
在这个背景下,refena 出现在了我的视野里。它在 pub.dev 上的发布时间不算长,社区资料也不算多,但它的几个设计方向恰好打在我在鸿蒙适配中遇到的痛点上。
第一,它是纯 Dart 实现,核心不依赖任何平台插件通道。这意味着 OpenHarmony 的 Flutter 运行时不需要额外实现什么原生接口,refena 就能正常工作。
第二,它走的是“编译期生成 + 显式依赖容器”的路线。开发者定义一个 repository(仓储),框架通过代码生成来管理依赖关系和监听绑定。类型错误在编译期就能暴露,而不是运行时才报。
第三,它的响应式更新是细粒度的,理论上可以做到只刷新依赖了某块状态的那个 widget,而不是整个页面子树。这一点在鸿蒙真机上的表现差异非常明显,后面我用登录态模块做了实测对比。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. refena 的响应式模型:repositories、stores 与增量刷新如何降低心智负担
2.1 先理解它的分层:业务逻辑和 UI 状态分离
refena 的模型和 Riverpod 有点神似,但不完全一样。它的核心分层大概是这样的:
- repository(仓储层):负责业务逻辑和状态变更,类似 Riverpod 的 Notifier,但职责更聚焦。登录、退出、刷新 token 这类操作都放在 repository 里。
- state(状态数据):repository 内部持有的数据对象,比如
AuthState里的 userId 和 token。state
