说实话,看到“Flutter for OpenHarmony 实战:数独算法与求解器深度解析”这个标题,我自己先愣了一下。因为这俩词放一块儿,信息量其实非常大:一边是跨端 UI 框架里迭代最快的 Flutter,一边是国产操作系统里关注度飙升的 OpenHarmony,中间还夹着“数独算法”这种听起来偏算法岗的硬核东西。很多人的第一反应是“Flutter 不是跑在 Android/iOS 上的吗,跟 OpenHarmony 有什么关系”,第二个反应是“数独不就 9x9 填数字吗,有什么好深度解析的”。
我最初接触这个组合,是帮团队评估在 OpenHarmony 设备上做一款离线小游戏 demo 的可行性。当时市面上能查到的资料很零散,Flutter 官方还不直接支持 OpenHarmony,需要走社区 fork 的引擎和适配层,数独部分又涉及盘面生成、求解、难度判定这些算法细节。踩完一圈坑之后,我觉得这套组合其实特别适合拿来写一篇实战拆解。一方面,Flutter 在 OpenHarmony 上跑起来这件事本身就值得记录,环境怎么搭、工程怎么配、哪些坑别踩;另一方面,数独这个游戏麻雀虽小五脏俱全,从数据结构到回溯算法再到 UI 联动,刚好能把“算法在真实 App 里怎么落地”这件事讲透彻。
这篇文章适合这几类人看:想在 OpenHarmony 设备上跑 Flutter 应用的移动端开发,对数独生成/求解算法感兴趣的算法爱好者,以及想从零搭一个跨端小游戏练手的初级开发者。我会按环境搭建、核心数据结构、求解器实现、题目生成、UI 联调、问题排查这几个维度逐个拆,尽量把每一步的“为什么这么做”也讲清楚。
1. 项目整体拆解与技术选型思路
动笔之前,先把这个项目到底在做什么、边界在哪理清楚。标题里三个关键词,对应三层完全不同的技术栈,选型和目标也不一样,混在一起很容易写乱。
1.1 Flutter 与 OpenHarmony 结合的真实形态
一听到“Flutter for OpenHarmony”,很多人下意识以为是 Flutter 官方出的分支,其实不是。截至目前,Flutter 官方主仓库并没有把 OpenHarmony 列入稳定支持的 target。实际落地靠的是社区主导的适配方案,你可以在 Gitee 上找到 openharmony_flutter 这类镜像仓库,它是基于 Flutter stable 分支打补丁, 추가了 OpenHarmony 平台的 embedding 层和 build 工具链。
也就是说,工程结构跟标准 Flutter 工程非常像,依然是 pubspec.yaml 管理依赖,lib/main.dart 写 Dart 逻辑,但底层编译产物不是 Android 的 APK,也不是 iOS 的 ipa,而是 OpenHarmony 的 HAP(HarmonyOS Ability Package)。运行时要依赖鸿蒙侧的 Flutter 引擎库,这一块由适配层负责编译成 .har 或直接打进去。开发 IDE 也不能只用 Android Studio 或 VS Code 一条路走到黑,通常要用 DevEco Studio 打开原生工程做签名和烧录,Dart 代码部分则继续用你熟悉的 Flutter 工具链编辑调试。
我个人的建议是:不要指望把 OpenHarmony 当成 Android 的“又一个分支”来无脑编译,最好把整个适配层想象成“Flutter 引擎在 OpenHarmony 运行时上的一层移植”。理解了这个抽象层级,后续遇到编译错误时你才能一眼看出问题出在上层 Dart 还是下层平台通道。
1.2 为什么偏偏选数独作为实战载体
数独看着简单,但它天然具备一个完整算法的教学闭环:规则明确——9x9 网格中每行、每列、每个 3x3 宫格内填入 1-9 且不重复;状态清晰——盘面可以用一个二维数组描述;算法有层次——校验、唯一解、回溯求解、随机出题、难度评估,每一步都是可独立拆解的模块。
在 Flutter 里做数独还有一个额外的好处:UI 形态非常匹配 Flutter 的布局模型。数独盘面就是一个 GridView,格子天然等宽等高,手势交互也可以用 GestureDetector 精细控制。也就是说,算法层可以完全和 UI 层解耦,先纯 Dart 实现并测试逻辑,再套上 Flutter 的界面层做展示与交互,这个分离思路本身就适合复制到其他业务项目里。
另外一个原因也跟我自己接手的实际项目有关:当时我们评估 OpenHarmony 上的可用性,需要一个不依赖网络、不依赖传感器、不依赖后端服务,纯前端的完整项目来做踩坑验证。数独完美满足这些条件,而且它比 Todo App 有深度,又比商城项目轻量,是适配层移植验证的最佳样板之一。
1.3 技术栈分工与工程结构设计
在动手敲代码前,先明确各模块的职责:
- Dart 层负责数独盘面建模、合法性校验、回溯求解、题目生成和难度评估。这一层不依赖任何 Flutter 组件,纯 Dart 逻辑,便于单元测试。
- Flutter UI 层负责盘面渲染、用户点击选格、数字输入、高亮提示、计时和错误计数。算法层通过简单的接口暴露能力,UI 层不直接操作具体求解过程。
- 原生适配层只负责让 Flutter 引擎跑起来,处理剪贴板、文件存取、系统主题这些平台相关能力。数独业务本身不碰这一层。
我习惯把工程拆成 lib/model/(盘面模型)、lib/solver/(求解器)、lib/generator/(题目生成器)、lib/ui/(Flutter 页面)四块。这种分层最大的好处是:后面如果你想换个 UI 框架,或者把求解器单独打包成 Dart 库给终端项目用,都不需要大改核心代码。对数独这种逻辑密集的项目,测试驱动也更容易写——直接对纯 Dart 的那一层做单测就够了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数独盘面建模:从二维数组到约束模型
算法题里的数独盘面通常只要求一个 9x9 的 int[][],但真实 App 里,你还需要记录格子是否被锁定(题目给定的)、用户的输入是否冲突、候选数有哪些、当前选中了哪个格子。所以建模不能停留在“能跑通算法”的层面,得按产品需求来。
2.1 基础盘面结构实现
先定义最简单也最核心的数据结构。用 List<List<int>> 表示 9x9 网格,0 表示空格,1-9 表示已填入数字。为了后续扩展,我习惯包一层 SudokuBoard 类:
dart复制class SudokuBoard {
final List<List<int>> _grid;
SudokuBoard(List<List<int>> data) : _grid = _deepCopy(data);
int get(int row, int col) =
