尧图精选

鸿蒙App还需要传统首页吗?从原子化服务到任务直达的架构思考

🕒 发布时间:2026/9/14 9:31:29 📁 来源:尧图网络
2024年了我们真的还需要把“首页”做成App的宇宙中心吗做鸿蒙应用开发这段时间我经常被问到的一个问题不是“这个功能怎么实现”反而是个听起来有点反常识的讨论未来的鸿蒙 App还需要“首页”吗之所以会冒出这个念头是因为最近在复盘自己在 DevEco Studio 里折腾的几个鸿蒙 App 小项目。从基于 ArkTS 的界面搭建到流转、服务卡片、元服务的接入我发现鸿蒙这套系统对“入口”这件事的理解跟过去安卓/iOS 时代很不一样。过去我们讲 App 启动先甩给你一个首页所有业务从首页这个端点上铺开它既是导航站、又是流量广场、还是活动弹窗的投放位。但到了鸿蒙这里从“原子化服务”到“MetaService”再到系统级的意图框架处处都在渗透一个信息用户找的是任务结果不是你的页面层级。这篇文章我准备从需求切入聊聊“首页”这个概念在鸿蒙生态里为什么开始松动再结合我自己开发过程中碰到的真实工程问题对比一下哪些业务确实离不开首页哪些业务其实可以拿走以及如果我们要做“无首页”设计具体在代码和架构上该怎么下手。如果你是刚开始接触鸿蒙开发或者正在准备鸿蒙面试题、想看看纯血鸿蒙下的应用到底和传统 App 有什么本质不同这篇文章应该能给你一些比较落地的参考。1. 内容整体设计与思路拆解1.1 为什么“首页”会成为默认选项在讨论要不要去掉首页之前先得想明白首页是怎么变成“天经地义”的。传统移动应用里首页的核心价值有三个第一个是流量分发效率。产品经理会把所有希望用户看到的东西浓缩在首屏谁的入口位置靠前谁的点击率就高这件事在电商、新闻、社交类 App 里特别明显。第二个是业务承载。登录态、消息提醒、推荐流、运营位全都需要一个稳定的容器来落地。第三个是心智锚点。用户习惯“打开 App 先看首页”如果有一天打开抖音直接进到某个评论区很多人会以为 App 出 bug 了。这三个价值在过去十几年里被放大得越来越厉害甚至很多 App 的首页已经从“信息展示”变成了“商业竞价排名”。结果就演变出一种畸形状态首页越来越长、越来越重用户真正要完成的任务被淹没在运营位、弹窗和红点里。我在做早期的应用开发时也犯过同样的错误一上来就把首页设计成信息中枢结果每次启动都要拉取十几二十个接口白屏时间一长卸载率直线上升。后来我开始反思首页到底是为用户服务的还是为业务指标服务的1.2 鸿蒙给出的根本性变化入口不再只有一个鸿蒙和安卓/iOS 一个非常大的区别在于它从设计之初就不认为“App 启动页”是唯一的服务入口。鸿蒙的原子化服务可以理解为一种可被系统拆散、单独投放的服务形态。用户不需要先下载一个 App也不需要在一个大而全的首页里翻找而是通过服务卡片、碰一碰、扫码或者智能推荐直接触达某个具体功能。比如你在商场看到一个智能饮水机用鸿蒙手机碰一碰不用装 App就能在服务卡片上完成扫码购水、查看滤芯寿命这些操作。这背后的技术底座包括元能力Ability的拆分。一个应用可以有多个 Ability每个 Ability 都可能是独立的入口。服务卡片Form可以在桌面上直接展示业务核心信息比如快递进度、待办事项、运动步数。意图框架Intents允许开发者把服务“语义化”地连接给系统比如用户说“我要打车去机场”系统可以根据意图直接分发到对应的服务而不用你先打开某个出行 App 再输入出发地和目的地。跨端流转让同一个任务可以在手机、平板、车机、智慧屏之间接续而不是每个设备上都有一个“完整 App”。这些机制放在一起意味着一个非常关键的变化用户和能力的距离被大幅缩短首页这个中间层开始显得多余。我参与过一个鸿蒙 App 小项目的架构调整把原本“首页—二级页面—三级页面”的纵深结构改成“桌面卡片直达列表页”的偏平结构。结果非常出乎意料——核心任务完成率提升了很多而首页的 PV 和 UV 并没有出现预想中的断崖式下降因为很多原本被首页挡住的长尾功能反而通过服务卡片和搜索入口被重新找出来了。1.3 无首页不是没首页而是一张“动态首页”这里必须澄清一点说“鸿蒙 App 不需要首页”不等于所有应用都要把首页彻底删掉。更准确的说法是首页从“固定不变的大杂烩”变成“动态匹配的场景门户”。在过去首页的布局基本是产品经理拍脑袋定的顶部轮播图中间金刚区下方信息流再挂几个运营模块。但鸿蒙的“场景化”思路是谁在用、在什么设备上用、处于什么任务状态决定了用户看到什么。举例来说一个健身运动 App在手机上的启动首页可能是训练计划而在手表上首页可能直接是心率监测或运动开始按钮。一个智慧办公应用在平板上打开时首页可能是最近文档列表在智慧屏上打开时首页可能是正在进行的视频会议入口。一个购物应用晚上打开时首页可以直接落到“今日达”订单配送进度而不是千篇一律的“猜你喜欢”。这种能力的基础就来自鸿蒙对“设备形态”和“任务上下文”的感知。作为开发者如果你还在编写一套“所有设备通用”的首页页面那其实是把自己锁在了旧时代的开发范式里。所以整篇的探讨并不是为了推翻首页这个产品形态而是想理顺一个思路如果你在考虑做鸿蒙版本的 App时间精力有限是不是应该把“首页”的优先级降一降转而把资源投向卡片、意图、流转这类更贴鸿蒙生态的能力2. 核心细节解析与实操要点2.1 首页模式的四宗罪很多团队从安卓/iOS 转到鸿蒙时最容易犯的一个惯性错误就是把原来的 App 结构原封不动搬过来。这倒不是说搬过来一定不行而是你要意识到首页模式在鸿蒙生态里存在四个明显的短板。第一性能开销不划算。首页是信息密度最大的页面往往需要同时启动网络请求、图片加载、数据缓存、埋点上报。但在鸿蒙的分布式场景里用户可能从一个服务卡片点进来目标是直接看某条订单详情如果系统还要先经历一次完整首页的初始化体验就大打折扣了。第二信息冗余严重。手机屏幕本来就那么大硬塞进去几十个模块用户要为不想要的信息付出注意力成本。放在鸿蒙的“服务找人”理念下这是违背用户预期的。第三跨端适配极其痛苦。如果你开发的是面向手机、平板、车机、手表多端的应用那么首页的布局逻辑、尺寸适配、交互层级都得分别处理。凡是做过车机适配的人都知道一个复杂的首页在车机上的可用性往往非常差驾驶场景不允许用户在信息流里翻找功能。第四架构上很难做到服务复用。首页高度定制化导致 UI、业务、数据和逻辑强耦合想拆出原子化能力时得先跟首页这张“蜘蛛网”做斗争。2.2 鸿蒙里的“去首页化”能力地图在鸿蒙体系里如果你决定弱化或者去掉传统首页可以利用这些关键能力来承接原本首页负责的功能服务卡片以 Form 的形式把高频信息直接放到桌面上。用户不用点进 App就能完成查看、点击、甚至部分操作。卡片支持多种尺寸可以显示运动步数、天气、快递状态、待办事项等。元服务入口通过碰一碰、扫码、小艺建议、应用市场等入口直接拉起元服务。开发者可以把单业务功能发布为独立元服务用户用完即走。意图框架与分发鸿蒙把“语义理解”引入了系统级导航。比如用户想“支付停车费”系统根据语义匹配合适的服务推送相应的元服务卡片或免密支付卡片给用户。跨端流转与接续手机上看一半的视频可以流转到智慧屏继续播车机上发起导航下车后自动流转到手机继续步行导航。这类场景根本没有“首页”的参与空间重点在服务和状态的无缝衔接。后台任务与通知通过 NotificationKit、WorkScheduler 等系统能力把任务状态主动告知用户进一步降低用户主动打开 App 找信息的频率。这些工具组合起来相当于把原来首页承担的“找入口、看状态、做操作”三个职责一个个拆解到系统里更轻量、更智能的位置上。2.3 哪些类型的 App 可以大胆做减法根据我自己和同行们踩过的坑以下这些应用类别比较适合优先尝试“去首页化”或“首页极简化”工具类应用比如计算器、单位换算、扫码支付、查快递、记账。用户使用路径非常明确完全可以通过桌面卡片或元服务直达。智能家居类控制灯光、空调、窗帘用户要的是“快”场景触发也比信息流更能解决问题。运动健康类记录步数、心率、睡眠卡片就是天然的展示形态手表端展示效果远好于手机端首页。出行导航类高频操作用卡片承担比如实时路线、车牌限行提醒、停车位置记录。而内容消费类应用短视频、新闻、社区短期内其实离不开首页因为这类产品的核心就是推荐流用户需要不断接收新内容首页本身就是内容载体。所以这类应用在设计鸿蒙版时最优解不是“删掉首页”而是“首页弱化为服务卡片以外的轻量内容feed”同时利用鸿蒙的多设备能力把内容无缝切换到不同的屏幕上。2.4 哪些业务还是得老老实实保留首页同样也有一些业务强依赖首页的聚合价值。比如大型电商平台用户进来可能是为了签到、领券、浏览秒杀这时候如果直接把用户送进某个商品详情页可能会损失掉很多额外曝光。再比如金融类应用功能多、层级深、合规要求高首页作为导航中枢和风险提示层的意义短期内不可能被替代。所以我的建议是别搞“一刀切”。在鸿蒙的框架下你需要做到的是“场景化选择”。用户从桌面卡片进入就给他卡片对应的服务用户主动点开 App再呈现一个完整但精简的首页。首页的存在感应该从“唯一门户”降级为“多种入口之一”。3. 实操过程与核心环节实现3.1 工程架构上先为“无首页”做好准备这段话写给正在规划鸿蒙项目工程结构的开发者。如果你已经决定做“去首页化”的尝试第一步不是写页面而是调整模块划分。推荐采用HAP/HAR 分离的方式。HAPHarmonyOS Ability Package就是一个可独立部署的功能模块HARHarmonyOS Archive是静态共享包。简单理解HAP 是可以单独上架、分发和安装的基本单元HAR 则是公共代码库。你可以把一个鸿蒙应用工程拆成多个 HAP第一个 HAP 是传统 App 壳里面可以保留一个最简首页用来承接用户主动点击 App 图标。后面的 HAP 各自承载独立的元服务比如一个“快递服务” HAP里面就只有一个快递查询页面外加服务卡片。公共的网路请求库、数据存储、工具函数放在 HAR 里多个 HAP 共用。注意在 DevEco Studio 里配置多 HAP 工程时要留意 module.json5 里的 module.type以及 ability 的 export 配置。我之前刚开始配置的时候经常因为 ability 没有设置 exported 为 true导致其他模块无法拉起报错日志还不怎么明显排查了半天。代码层面一个简单的“元服务直达页面”场景可以用 Stage 模型来做 启动一个页面的时候通过want参数接收来源信息import { UIAbility, AbilityConstant, Want } from kit.AbilityKit; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // 通过 want.parameters 来识别用户入口来源 // 比如是从服务卡片进来的还是从桌面图标进来的 if (want.parameters?.targetPage orderDetail) { AppStorage.setOrCreate(initialPage, pages/OrderDetailPage); } else { AppStorage.setOrCreate(initialPage, pages/HomePage); } } }这么做的好处是同样一个应用入口不同用户看到的第一个页面也不同。3.2 用服务卡片替代首页的“状态展示”功能服务卡片是“去首页化”最直接、见效最快的手段。它的主要价值是高频信息无须打开应用即可看到。我拿一个运动 App 为例传统首页上最核心的信息是“今日步数”“卡路里消耗”“运动时长”。这些完全可以用服务卡片直接放到桌面上。卡片实现起来并不复杂用 ArkTS 写一个 Form 的卡片 UI再通过formBindingData更新卡片数据即可。卡片界面的简单 ArkTS 写法大概是这个样子let formData { stepCount: 8562, calories: 326, distance: 5.8km }; let formBindingData formProvider.formBindingData(formData);然后在FormExtensionAbility里更新import { formProvider, FormBindingData } from kit.FormKit; import { BusinessError } from kit.BasicServicesKit; export default class MotionCardFormAbility extends FormExtensionAbility { onAddForm(want: Want): formBindingData.FormBindingData { return formProvider.formBindingData({ stepCount: --, calories: --, distance: -- }); } onUpdateForm(formId: string) { // 实际项目中这里应该从数据库或者健康服务里拉取最新数据再调用 updateForm 更新到卡片 let newData: Recordstring, Object { stepCount: 9000, calories: 388, distance: 6.2km }; let formInfo: formBindingData.FormBindingData formProvider.formBindingData(newData); formProvider.updateForm(formId, formInfo).catch((err: BusinessError) { console.error(updateForm failed: ${JSON.stringify(err)}); }); } }我之前在实际开发时踩过的坑是卡片定时更新的频率限制。系统对onUpdateForm的触发有配额限制不是你想刷就能无限刷。如果用 WorkScheduler 来做后台定时任务也要注意精度和功耗之间的平衡。经验是卡片数据优先用“被动刷新”即数据变化时由服务端推送或端侧感知后立刻更新而不是定时轮询。3.3 意图框架和“无首页”的语义连接鸿蒙的意图框架给我的感受是它真正在尝试把“找功能”这件事系统化。比如用户使用“小艺建议”系统会按照时间、地点、用户习惯主动推送相关的元服务卡片。作为开发者我可以在module.json5里声明服务的意图能力。一段简化的意图声明{ skills: [ { actions: [ action.weather.query, action.express.query ], entities: [ { name: expressCompany, value: sf_express, zto, yto } ] } ] }这种方式等于告诉系统我这个服务能处理“查天气”和“查快递”这两个动作用户在系统层面发起这些请求的时候我的服务就会被推荐甚至直接拉起。实际体验下来这套机制对开发者最大的挑战不在“接入”而在“语义边界”。你把自己能干什么描述得越具体系统分发就越精准。但如果描述得过窄又可能错过潜在流量。我见过有的团队把元服务声明成“万能助手”结果意图匹配率极低系统根本听不懂它想表达什么。3.4 数据层如何支撑“动态首页”和“无首页”决策无论是保留一个轻首页还是彻底走“卡片元服务”的路线背后都离不开一套统一的数据层来支撑场景决策。我强烈建议做鸿蒙应用时不管页面形态怎么变数据层都单独抽一层至少在以下几个方面做好基础统一用户标识跨端流转的前提是人识别一致不然手机上的数据到平板上就断片了。场景化数据结构例如同一个运动数据在卡片上只需要聚合值在首页可能需要折线图、排行榜、历史记录。接口设计上最好一次给全由端侧按场景裁剪。本地缓存与同步鸿蒙应用特别依赖原子化场景这意味着用户可能在离线状态下拉起卡片。一定要把最近一次的有效数据放在本地数据库中不能一没网就白屏。我自己的做法是所有从卡片或者元服务入口进来的请求都走同一个数据仓库层页面只负责消费 ViewModel 里的数据。这样将来无论你是调整首页布局还是把某个模块改成卡片都不需要改业务逻辑。3.5 从“首页为王”到“任务直达”怎么过渡实操中最稳妥的路径不是“今天删首页明天上卡片”而是分成四个阶段盘点高频任务把现有首页上的功能按“使用频率”和“操作深度”排序。找出前20%的高频任务它们是最适合卡片化和元服务化的对象。做一套轻量首页保留必要的信息架构和大促活动位但把重复轮播、低效入口全部去掉后台做好灰度开关。卡片和意图逐个落地每拆一个高频任务就把对应的亏损数据点击率、完成率、崩溃率上线前、上线后各拉一周确认没有负向影响。逐步走向设备差异化手机端保留轻首页手表端用卡片取代首页车机上直接把首页替换为纯语音任务流。注意在整个过渡阶段千万不要忽略“降级方案”。一旦服务卡片或者意图框架拉起的页面在某个系统版本上出现兼容问题用户点桌面卡片没反应是很伤用户体验的。卡片相关内容要加 try/catch 兜底入口失败时至少能降级到打开主应用的首页。4. 常见问题与排查技巧实录4.1 服务卡片数据刷新失败这是我上手开发时第一个遇到的坑。服务卡片添加成功后一直显示“--”怎么调都不出数据。后来发现在 DevEco Studio 里卡片刷新有两个不同的链路一种是onAddForm时写入的静态数据另一种是后续通过formProvider.updateForm更新的数据。如果你在onAddForm之后立刻调用updateForm大概率会被系统忽略。正确做法是在onAddForm里只返回初始数据然后在onUpdateForm或者自己触发的事件中更新。另外还要检查form_config.json里有没有配置updateEnabled为 true默认并非总是打开。4.2 跨端流转不成功跨端流转对工程代码的要求是“模块尽量无状态”。如果你的页面里到处是全局变量、单例对象、进程内缓存流转过去后另一台设备就会“失忆”。我碰到的典型问题手机上的视频页面流转到平板后URL 参数传过去了但播放进度丢掉了。排查许久发现播放进度存在一个局部的静态变量里并没有写入公共的分布式数据源。解决方案是使用鸿蒙的分布式数据服务或者把关键状态随流转参数同步过去。一个小技巧是在流转前把页面状态序列化成一个 JSON 字符串塞进want.parameters目标端再反序列化恢复。4.3 元服务入口被系统“冷落”理论上接入意图框架后系统会在合适时机推荐你的服务。但实际你会发现如果刚上架、没有任何用户数据系统大概率不会轻易推荐。鸿蒙的做法有点像一个“智能推荐系统”它需要积累用户使用习惯才会把合适的服务推到前台。所以不要指望第一天接入意图框架就有大量分发。更好的策略是同时布局服务卡片、碰一碰入口把线下和桌面场景的流量先做起来再让系统后台慢慢学习用户的好感度。4.4 首页和卡片的埋点体系冲突团队最容易被忽略的地方是数据口径。过去所有行为都往“首页曝光”“首页点击”上归因现在很多任务从卡片完成了首页数据大幅下跌老板一看就慌了。我建议从设计开始就把“任务完成率”作为北极星指标而不是“首页PV”。卡片、元服务、首页都是完成任务的路径数据报表里应该统一归因到任务维度按入口分组查看占比这样才能真实反映“去首页化”有没有带来收益。排查点可能原因解决思路卡片不更新updateEnabled 未开启 / 刷新频率超限检查 form_config改用重要事件触发更新流转后页面空白目标设备没有对应 HAP 或 Ability 未导出检查 module.json5 的 exported 配置确认目标设备已安装对应模块意图匹配不准skills 的 actions 描述太宽泛或太窄收敛动作语义参考系统推荐的 action 列表首页数据跌幅大用户迁移到了卡片/元服务路径按任务维度重新归因不要只看首页指标卡片内图片不显示本地资源路径在卡片中不可直接引用使用 media 资源或通过 Base64/URL 方式传递图片动态首页卡顿首屏一次性拉取数据过多精简单模块加载冷启动时只渲染首屏必要组件5. 开发环境与工程配套5.1 DevEco Studio 与鸿蒙应用工程落地聊了这么多思路还是要回到工程上。在真机或者模拟器上跑一个支持“卡片元服务”的鸿蒙项目需要用到的核心工具还是 DevEco Studio。现阶段纯血鸿蒙应用的开发基本都依赖这个 IDE 来配置签名、打包 HAP、调试卡片和元服务。如果你是刚入手建议先理解这几个概念API Version不同版本的系统对应不同的 API 等级很多新接口只在较新的 API 上开放。HAP 与 HARHAP 是可部署的功能包HAR 是共享静态库。项目大了之后拆模块是线性的必然选择。module.json5每个 HAP 的配置文件里面可以声明 ability、skills、元服务信息、卡片配置等。Entry/HAP 的安装方式真机调试卡片时需要把 HAP 安装到设备上再在桌面手动添加卡片。模拟器的卡片支持也比较成熟但跨端流转能力的测试基本得靠真机。工程搭建阶段有个小建议直接创建“Empty Ability”模板时默认生成一个 MainAbility 和一个 Index 页面。你在这个基础上去扩展卡片、元服务、流转能力会轻松很多不要一上来就套复杂的 MVVM 框架鸿蒙原生状态管理State、Prop、Link、Observed这些用好了小项目完全足够。5.2 使用模拟器和真机测试时的差异模拟器在开发阶段确实方便但它不能完全替代真机。尤其是涉及服务卡片、跨端流转、分布式数据管理这类系统级能力模拟器经常表现得很“理想化”真机上才会暴露网络权限、硬件能力、功耗调度等真实问题。我印象比较深的一次模拟器上卡片刷新特别流畅一到真机上就频繁失败。后来定位到是真机的后台调度策略更严格WorkScheduler的最小间隔限制和电池优化策略把定时任务给掐了。所以建议大家在开发鸿蒙应用时有条件一定要准备至少一台真机并且保持系统版本尽量新毕竟鸿蒙迭代速度不慢旧版本设备对新接口的支持往往会有差别。6. 结尾我的实操体会从“首页是宇宙中心”到“服务应该主动找用户”这个转变不只是一次 UI 改版而是整个产品思维和技术架构的调整。我个人在动手做鸿蒙 App 小项目时收获最大的并不是学会了多少新 API而是被迫重新去思考用户真的需要一个“ App”还是只需要一个“结果”如果你现在正准备从零做一个鸿蒙应用我的建议是别急着把安卓/iOS 那套首页设计搬过来。先把业务里最高频的几个任务列出来思考它们在卡片上的形态是什么在语音场景下怎么表达在手表上如何呈现。你会发现当你想明白这些问题时“首页”到底该长什么样、该承载什么答案会自己浮现出来。最后再分享一个小技巧在做服务卡片或者元服务时不要只在代码里测试多花点时间在桌面和小艺建议里真实点一点。很多时候你觉得“这样肯定没问题”的交互在实际桌面上会暴露出各种细节问题。鸿蒙生态的体验恰恰就藏在这些细节里。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →