Android 转鸿蒙,最容易踩的三处隐形坑
子玥酱(掘金 / 知乎 / ZEEKLOG / 简书 同名)
大家好,我是子玥酱,一名长期深耕在一线的前端程序媛 👩💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。
我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括前端工程化、小程序、React / RN、Flutter、跨端方案,
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。
技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:掘金、知乎、ZEEKLOG、简书
创作特点:实战导向、源码拆解、少空谈多落地
文章状态:长期稳定更新,大量原创输出
我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。
子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”
持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱
文章目录
引言
很多有 Android 经验的开发者,在真正进入鸿蒙项目时,第一阶段通常都很顺。
原因很简单:
大多数表层能力,看起来都“差不多”。
- 都有生命周期
- 都有组件化
- 都能分层架构
- 都能写 MVVM
于是很容易得出一个危险判断:
“迁移成本其实不高。”
但真正做进中后期,问题会突然集中爆发:
- 多窗口状态混乱
- 后台能力失控
- 交互行为不稳定
而最诡异的是:
这些问题,在 Android 经验里几乎找不到解释。
这说明真正的坑,不在 API,而在运行时模型的断层。
下面这三处,是最容易被忽略、却几乎每个团队都会踩到的隐形分水岭。
第一坑:把 Ability 当成 Activity
这是最常见,也最隐蔽的一次误判。
表面上看:
- 都有生命周期回调
- 都承载 UI
- 都是应用入口
于是很自然地复用 Android 心智:
onCreate(){initViewModel()}onDestroy(){clearState()}问题在于——
Ability 的存在意义,从来不是“页面容器”。
在鸿蒙里,Ability 更接近:
系统级运行单元。
它可以:
- 长期存在而不销毁
- 被多个窗口复用
- 在无 UI 情况下继续运行
- 被系统跨设备调度
这意味着一件根本性的事:
Ability 生命周期 ≠ UI 生命周期。
如果你继续把状态绑在 Ability 销毁上:
onDestroy(){this.saveTempState()}你迟早会遇到:
状态还没保存,UI 已经换了一轮。
正确视角:Ability 只是“运行壳”
真正应该稳定存在的,不是 Ability,
而是任务状态。
classTaskStore{private state: TaskState getState(){returnthis.state }}Ability 只是:
附着到 Task 上的一个入口。
这一步认知不变,后面所有架构都会歪。
第二坑:把多窗口当成“多页面”
Android 里所谓的多窗口,本质还是:
弱多窗口 + 单任务栈。
所以很多迁移代码天然假设:
this.viewModel =newPageViewModel()每开一个窗口,就新建一套状态,在手机时代,这几乎没问题。
但在鸿蒙 PC:
窗口不是页面副本,而是任务视图。
同一个任务可能:
- 在两个窗口同时展示
- 被拖拽成独立面板
- 在后台继续执行
如果仍然按“页面级状态”设计:
classPageViewModel{ data: Data }结果一定是:
窗口 A 改了数据,窗口 B 完全不知道。
正确模型:状态必须归属于 Task
classTaskContext{ sharedState: Data }UI 只做一件事:
订阅 Task,而不是拥有状态。
taskContext.observe(data =>{this.render(data)})这一步不做,PC 多窗口永远只是看起来支持。
第三坑:继续用“页面驱动”的架构思维
这是最深的一层坑,也是最晚才会暴露的。
Android 的核心驱动关系是:
页面 → 触发业务 → 请求数据 → 渲染页面
也就是:
一切从 UI 开始。
所以经典分层才成立:
- ViewModel 依附页面
- UseCase 被页面调用
- Repository 为页面服务
但鸿蒙 PC 改变了一件根本性的事:
业务可以在没有 UI 的情况下长期存在。
例如:
- 后台下载
- 跨窗口编辑
- 持续通信任务
- 跨设备协同
这时候再问一个问题:
如果没有页面,谁来驱动业务?
Android 架构在这里直接失效。
新的驱动中心:任务,而不是页面
鸿蒙 PC 更接近这样的结构:
classTask{start()stop()attachUI(ui: TaskUI)}UI 的角色从:
业务入口
变成:
任务的一个观察窗口。
task.attachUI(this)这就是整条架构分水岭:
从页面驱动 → 任务驱动。
为什么这三处坑几乎必踩
因为它们都不是:
- API 问题
- 语法问题
- 框架问题
而是:
操作系统时代切换带来的心智滞后。
简单说就是一句话:
你在用移动时代的因果关系,解释桌面时代的运行逻辑。
只要这层不变:
- 架构越“规范”越不稳定
- 分层越“干净”越难协同
- 代码越“像 Android”问题越深