1. 项目概述与技术选型思路
1.1 这个项目到底在做什么
先说实话,第一次听到“便单服务类”这个叫法的时候,我也愣了一下。翻译成人话,其实就是便签/笔记类应用服务——用户随手记一条想法、列一个待办清单、存一句灵感,然后下次打开还能找到。这个品类在应用商店里看起来简单,真正上手做才发现坑不少:数据怎么存才不丢、怎么跨页面同步、如何在系统资源有限的场景下保证流畅,每一项都牵扯到具体的架构决策。
「便笺星(NoteStar)」是我用 Flutter 作为跨端框架、跑在 HarmonyOS 6.0 上的一个真实项目。选这个组合的原因很简单:鸿蒙现在的用户量已经不小了,但纯 ArkTS 开发的学习成本和生态迁移成本对很多团队来说还是偏高。Flutter 的渲染引擎和 Dart 语言本身是中立的,通过鸿蒙提供的 Flutter 适配层可以直接把现有的 Flutter 代码跑在鸿蒙设备上,这就让“一套代码、多端运行”从口号变成了可行的工程路径。
这个项目适合谁参考?如果你正在做跨平台应用、需要对鸿蒙设备做兼容、或者只是想看看 Flutter 在非 Android/iOS 平台上的真实表现,那这篇文章值得你花几分钟读完。我会把选型逻辑、持久化方案、核心功能拆解和调试记录都放出来,能直接抄作业的地方绝不含糊。
1.2 为什么选 Flutter 而不是直接写 ArkTS
这个问题我当初纠结了很久。鸿蒙 6.0 的 ArkTS 已经相当成熟,用原生方式开发肯定是最“正统”的路线。但我最终选了 Flutter,核心理由有三条。
第一,代码复用率。团队手里已经有一套基于 Flutter 的便签应用,如果换 ArkTS 重写,工作量不是翻倍,是直接翻三倍——UI 层、业务层、数据层全部推翻。而用 Flutter 的鸿蒙适配层,UI 代码和业务逻辑基本可以原封不动搬过来,只需要针对鸿蒙的系统能力做一层薄薄的适配。
第二,Flutter 的渲染管线在鸿蒙上表现并不差。很多人以为 Flutter 只能跑 Android 和 iOS,实际上鸿蒙官方社区和 OpenHarmony 生态很早就开始了 Flutter 引擎的移植。到 HarmonyOS 6.0 这个节点,Flutter 应用的帧率、内存占用、启动耗时都已经到了可用的水平。我在 NoteStar 里做了简单的压测,普通的列表滑动和页面切换基本稳定在 60 帧。
第三,生态和招聘。Flutter 的开发者基数比 ArkTS 大得多,遇到问题搜索引擎一抓一大把。用 Flutter 意味着以后想适配其他平台(比如 Windows、macOS)也有现成的路子。
当然,选 Flutter 不是没有代价。鸿蒙有一些独特的能力,比如原子化服务、分布式数据流转,这些在 Flutter 里不能直接调用,必须通过 platform channel 桥接到鸿蒙原生侧。这个部分的开发难度比纯 ArkTS 高一些,后面我会专门说这块怎么处理。
提示:如果你是个人开发者、小团队,或者核心诉求是“尽快把业务跑起来”,Flutter + 鸿蒙适配层的方案性价比很高。如果你要做深度的系统级应用、大量依赖鸿蒙分布式特性,那还是老老实实写 ArkTS。
1.3 便笺类应用的核心难点拆解
便笺应用看起来简单,实际上它是一个非常典型的“轻交互、重数据”类应用。轻交互是说界面逻辑不复杂,无非是列表、编辑页、搜索、设置几个页面;重数据是说所有价值都在用户沉淀的笔记内容上,数据一旦丢失,用户对产品的信任就瞬间归零。
所以 NoteStar 的核心难点可以拆成三块:
- 持久化策略:数据存哪里、怎么存、怎么保证不丢、怎么在应用被杀掉之后还能恢复;
- 数据组织:便笺不是一堆孤立字符串,它需要支持分类、标签、置顶、归档、全文搜索这些操作,所以底层的存储模型必须有扩展性;
- 性能体验:用户打开应用的第一诉求是“快速记一笔”,如果冷启动要 3 秒、列表滑动掉帧、搜索要转圈,那不管功能多全,留存率都不会好看。
这三点听起来是常识,但实际落地时每一步都有细节。接下来我从持久化方案讲起,这是整个项目的基石。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 持久化存储方案剖析与落地设计
2.1 持久化技术选型:轻量偏好 + 关系型数据库双层架构
持久化存储这个事,很多人第一反应是“直接上 SQLite”。这没有错,但对于便笺应用来说,如果所有数据都塞进数据库,反而会带来不必要的复杂性和性能开销。我的方案是做一个双层架构:
上层是 SharedPreferences(轻量键值对),用来存用户偏好、设置项、上次打开的页面索引、主题颜色这类轻量数据。这类数据的特点是单条体积小、读写频率低、不需要复杂查询,用键值对最合适。Flutter 侧对应的是 shared_preferences 插件,在鸿蒙上也提供对应实现,可以直接用。
下层是关系型数据库(SQLite/Drift),用来存便笺的核心数据。每一张便笺包含标题、正文、创建时间、修改时间、分类、标签、置顶状态、归档状态等结构化字段。数据库的查询能力强,可以支持 WHERE 过滤、ORDER BY 排序、LIKE 搜索,这些都是便笺列表页和搜索页的基础。
两层之间通过一个仓储层(Repository)统一暴露接口,上层页面不关心数据到底存在哪里,只需要调用 getNotes()、saveNote(note)、deleteNote(id) 这样的方法。这种设计的最大好处是后期如果要换存储引擎(比如换到鸿蒙原生的 relationalStore),只需要重写仓储层的实现,页面代码一行都不用动。
2.2 数据表设计与索引优化
便笺表我命名为 note,字段设计如下:
dart复制class Note {
int id; // 主键,自增
String title; // 标题
String content; // 正文内容
int categoryId; // 分类ID,外键关联 category 表
List<String> tags; // 标签列表,存储为 JSON 字符串
bool isTop; // 是否置顶
bool isArchive; // 是否归档
