你真要在鸿蒙和 Android 上各写一套业务逻辑吗?那需求改一次你准备加几天班?
本文探讨了Android与鸿蒙(HarmonyOS)应用开发中的代码复用策略,提出了四个复用层级:协议与模型、业务规则、数据层和UI层。作者强调应优先复用"事实"而非代码写法,建议通过OpenAPI/Protobuf统一接口契约,采用跨平台核心库或DSL处理核心业务规则,同时保持UI层独立但统一状态管理。文章推荐Clean Architecture分层设计,采用单仓多端工程结构
👋 你好,欢迎来到我的博客!我是【菜鸟学鸿蒙】
我是一名在路上的移动端开发者,正从传统“小码农”转向鸿蒙原生开发的进阶之旅。为了把学习过的知识沉淀下来,也为了和更多同路人互相启发,我决定把探索 HarmonyOS 的过程都记录在这里。
🛠️ 主要方向:ArkTS 语言基础、HarmonyOS 原生应用(Stage 模型、UIAbility/ServiceAbility)、分布式能力与软总线、元服务/卡片、应用签名与上架、性能与内存优化、项目实战,以及 Android → 鸿蒙的迁移踩坑与复盘。
🧭 内容节奏:从基础到实战——小示例拆解框架认知、专项优化手记、实战项目拆包、面试题思考与复盘,让每篇都有可落地的代码与方法论。
💡 我相信:写作是把知识内化的过程,分享是让生态更繁荣的方式。
如果你也想拥抱鸿蒙、热爱成长,欢迎关注我,一起交流进步!🚀
0. 先把目标说清楚:你到底想复用到什么程度?
我把复用分 4 档(别一上来就追求“最大复用”,那是给自己找罪受🙃):
- 协议与模型复用(强烈推荐):接口契约、数据模型、错误码、埋点事件定义
- 业务规则复用(推荐):价格计算、校验规则、排序/筛选、风控策略
- 数据层复用(视情况):缓存策略、离线策略、Repository 逻辑
- UI 复用(谨慎):鸿蒙 ArkUI vs Android(Compose/XML)差异很大,强行统一通常得不偿失
1) 代码复用策略:别复用“写法”,复用“事实”✅
1.1 第一优先级:接口契约与数据模型(最稳)
把“事实”写成一个 单一来源,两端生成代码或手写映射都行:
- OpenAPI:定义 REST 接口 + 模型 → 两端生成客户端/模型
- Protobuf/JSON Schema:定义模型/事件 → 两端生成/校验
- 埋点事件表:统一事件名、字段、枚举值,避免两端各叫各的(最后数据平台哭给你看😭)
示例:Protobuf(或任何 schema)先定义一个 LoginResult
message LoginResult {
string userId = 1;
string token = 2;
int64 expiresAt = 3;
}
两端各自生成/解析,然后进入各自的 Repository。你会发现:复用的不是代码,是“数据结构的真相”。
1.2 第二优先级:核心业务算法/规则(建议用“可移植核心”)
如果你们确实有“同一套规则两端必须一致”(比如优惠计算/风控/离线索引)——建议用下面两种路线之一:
路线 A:用跨平台核心库(Rust/C++)
- 优点:真正一份核心逻辑,两端绑定调用(Android JNI;鸿蒙 NAPI/Native 接入)
- 缺点:工程复杂度上升、调试门槛更高
路线 B:用“规则 DSL/配置化”
- 把规则做成 JSON/DSL,客户端只是解释执行
- 优点:发布灵活,灰度方便
- 缺点:解释器也要一致,性能要评估
我个人很现实😅:除非你们“必须强一致”,否则优先做 模型+规则对齐,不要一上来就上跨平台 Native 核心把团队拖进深坑。
1.3 第三优先级:网络/存储框架别强行复用
鸿蒙侧(ArkTS/ohpm/hvigor)和 Android(Gradle/Kotlin)生态不同。你复用网络层实现,往往会变成:
“为了省 5% 代码,多写 30% 适配胶水” 🤡
所以我建议:
- 网络库、线程模型、存储实现:各端用各端成熟方案
- 统一的:Repository 接口、错误模型、重试策略、缓存策略规范
2) UI 层差异处理:别统一 UI,统一“状态与意图”😤
2.1 共同点:都应该走“单向数据流”
不管 Android 是 Compose 还是传统 View,鸿蒙是 ArkUI,UI 层都建议这样:
UI(展示) ← State(状态) ← Reducer/UseCase(业务) ← Intent/Action(用户意图)
你统一的是:
State的结构(页面需要哪些状态)Intent的集合(用户能做哪些动作)Effect的定义(导航、弹窗、Toast、埋点)
2.2 差异点:生命周期/导航/线程模型,各端自己兜
UI 层差异通常集中在:
- 页面/Ability 生命周期 vs Activity/Fragment 生命周期
- 路由栈(鸿蒙的 Ability/页面路由) vs Android Navigation
- 权限弹窗机制、系统能力调用方式
- 渲染与重组的“敏感点”(ArkUI 重组 vs Compose 重组)
策略:UI 层只做三件事:
- 把用户操作变成
Intent - 订阅并渲染
State - 处理
Effect(导航/弹窗/权限)
其他统统别塞 UI 里,不然两端都变“屎山 UI”😅
3) 业务层抽象:用 Clean Architecture/MVI 把两端“对齐但不绑死”✅
3.1 建议的分层(两端同一张图)
- Domain(纯业务):UseCase、实体、业务规则、错误模型
- Data(数据实现):Repository 实现、网络/缓存/数据库
- Presentation(表现层):ViewModel/Store,产出 State/Effect
- UI(平台层):ArkUI / Android UI 具体实现
关键:Domain 层要尽可能“无平台依赖”。
这样你就算不做“一份代码复用”,也能做到“两端结构一致”,团队协作会顺很多🙂
3.2 一套跨端通用的“Intent/State”定义(示意)
你可以把“页面协议”当成跨端合同:
// 伪代码:概念示意(你可以用 TS 文档/Schema 来管理)
type LoginIntent =
| { type: 'Submit'; username: string; password: string }
| { type: 'OpenPrivacy' }
| { type: 'RequestPermission' }
type LoginState = {
loading: boolean
errorMsg?: string
userName: string
}
type LoginEffect =
| { type: 'Toast'; message: string }
| { type: 'Navigate'; target: 'Home' }
鸿蒙端 Store/VM 产出这些;Android 端 ViewModel 也产出这些。
你就实现两套“胶水 UI”,但业务语义完全一致,这就是“架构复用”的含金量😤
4) 工程组织方式:我推荐你用“单仓多端 + 共享规范层”📦
4.1 目录结构(长期不乱的那种)
repo/
shared-spec/ # OpenAPI/Proto/埋点事件表/错误码/文档(强烈建议独立)
shared-domain-doc/ # 领域模型与用例说明(不一定共享代码,但共享设计)
harmony/ # 鸿蒙工程(ohpm/hvigor)
entry/
features/
common-ui/
common-data/
android/ # Android 工程(Gradle)
app/
features/
core-ui/
core-data/
tools/ # 代码生成、校验脚本、CI
4.2 依赖管理原则(别让“共享模块”变成垃圾场)
shared-spec:只放契约(schema、文档、生成脚本),不放平台实现- 端内
core-data:实现 Repository,但必须遵守 Domain 接口 - Feature 模块:只依赖 Domain 接口,不直接依赖底层实现(避免“牵一发动全身”)
4.3 CI 的关键门禁(强烈建议)
- schema 变更必须跑生成 + 编译两端(不然你今天改字段,明天两端都炸😅)
- lint/格式化统一
- 核心用例的契约测试(至少对错误码、关键字段做校验)
一个最实用的落地建议:先做到“语义一致”,再追求“代码一致”🙂
你会发现:
- 只要 State/Intent/Effect + API 契约 + 错误模型统一,两端就不会“一个叫 A 一个叫 B”
- 业务规则如果真的要求一致,再逐步引入跨平台核心库(别一上来上硬菜🥲)
📝 写在最后
如果你觉得这篇文章对你有帮助,或者有任何想法、建议,欢迎在评论区留言交流!你的每一个点赞 👍、收藏 ⭐、关注 ❤️,都是我持续更新的最大动力!
我是一个在代码世界里不断摸索的小码农,愿我们都能在成长的路上越走越远,越学越强!
感谢你的阅读,我们下篇文章再见~👋
✍️ 作者:某个被流“治愈”过的 移动端 老兵
📅 日期:2025-11-05
🧵 本文原创,转载请注明出处。
更多推荐



所有评论(0)