HarmonyOS 实战:6 种实现实时数据更新的方案全解析(含完整 Demo)

摘要

在当下的应用开发中,用户体验越来越依赖"实时性"。消息要第一时间送达、订单状态要立刻刷新、数据变化不能延迟......这些需求推动了"实时数据更新"成为应用的必备功能。在鸿蒙系统(HarmonyOS)中,我们既可以用系统内置的数据能力(DataAbility、DataBus),也可以用事件驱动(发布订阅)、后台服务,甚至和远程服务器保持 WebSocket 长连接。不同的方案适合不同的场景,本文会带大家从原理到实战,结合代码一步步拆解。

引言

假设你正在做一个电商应用:用户提交订单后希望能立刻看到订单状态更新;商家端改价后,用户端价格立刻刷新;再比如做一个股票类 App,行情数据需要秒级同步。这类场景在鸿蒙中都可以实现。

那怎么做呢?常见的方式包括:

  • DataAbility:适合模块内、应用间的数据共享和通知。
  • 发布-订阅(Publish-Subscribe):轻量、解耦,常用在组件交互。
  • 后台服务(ServiceAbility):适合长期任务,比如轮询服务器。
  • WebSocket:和后端保持实时通信。
  • DataBus:模块间的消息和数据同步。

接下来,我们用几个实际场景来展开。

用发布-订阅实现应用内实时更新

发布-订阅是应用内实时通知最常见的方式,模块之间不用直接耦合,只要关心"订阅什么事件"和"发布什么事件"即可。

场景:聊天应用消息刷新

用户在 A 页面发了一条消息,B 页面需要立刻刷新列表。

这时可以用事件分发,避免两个页面硬编码依赖。

Demo 代码

ts 复制代码
// 定义一个事件 key
const EVENT_MESSAGE_UPDATE = "chat_message_update";

// 发布者(比如在发送消息后触发)
import eventEmitter from '@ohos.events.emitter';

function sendMessage(content: string) {
  // 假装这里调用了服务端 API 成功
  console.info("发送消息成功: " + content);

  // 发布事件,通知其他模块刷新
  let eventData = {
    data: {
      message: content
    }
  };
  eventEmitter.emit({ eventId: 1, eventName: EVENT_MESSAGE_UPDATE }, eventData);
}
ts 复制代码
// 订阅者(比如消息列表页面)
import eventEmitter from '@ohos.events.emitter';

function registerMessageObserver() {
  eventEmitter.on({ eventId: 1, eventName: "chat_message_update" }, (data) => {
    console.info("收到消息更新: " + JSON.stringify(data));
    // 在这里更新 UI,比如追加到聊天列表
  });
}

说明

  • eventEmitter.emit 是发布事件。
  • eventEmitter.on 是订阅事件。
  • 事件 ID 和事件名需要保持一致,不然收不到。

这样就能做到:一个页面发消息,另一个页面自动更新。

用后台服务定期获取数据

有些场景下我们不依赖消息推送,而是主动去服务器拉取,比如天气数据、股票行情。这里就要用到 ServiceAbility。

场景:股票行情定时刷新

后台服务定时请求行情接口,前台 UI 通过事件接收并刷新。

Demo 代码

ts 复制代码
// MyStockServiceAbility.ets
import UIAbility from '@ohos.app.ability.ServiceExtensionAbility';
import eventEmitter from '@ohos.events.emitter';

export default class MyStockServiceAbility extends UIAbility {
  onCreate() {
    console.info("Stock Service started");
    this.startPolling();
  }

  startPolling() {
    setInterval(async () => {
      // 模拟请求股票接口
      let price = (Math.random() * 100).toFixed(2);
      console.info("拉取到最新股价: " + price);

      // 推送事件给 UI
      eventEmitter.emit({ eventId: 2, eventName: "stock_price_update" }, {
        data: { price }
      });
    }, 5000); // 每 5 秒刷新一次
  }
}
ts 复制代码
// 前台页面订阅股价更新
import eventEmitter from '@ohos.events.emitter';

function registerStockListener() {
  eventEmitter.on({ eventId: 2, eventName: "stock_price_update" }, (data) => {
    console.info("UI 收到最新股价: " + data.data.price);
    // 在这里刷新界面
  });
}

说明

  • ServiceAbility 适合后台运行,不会被 UI 销毁影响。
  • setInterval 定时拉取数据,实际项目中可换成真正的 HTTP 请求。
  • UI 层和后台服务解耦,只靠事件通信。

用 WebSocket 做实时推送

如果是消息、通知、行情这类高实时性场景,WebSocket 是更合适的。客户端和服务端保持长连接,一旦有数据,立刻推送。

场景:股票行情实时推送

相比上面的轮询方式,WebSocket 更节省资源,延迟更低。

Demo 代码

ts 复制代码
import WebSocket from '@ohos.net.webSocket';

function connectWebSocket() {
  const ws = new WebSocket("ws://echo.websocket.org"); // 测试用 echo 服务

  ws.onopen = () => {
    console.info("WebSocket 已连接");
    ws.send("订阅股票行情");
  };

  ws.onmessage = (msg) => {
    console.info("收到行情推送: " + msg.data);
    // 在这里更新 UI
  };

  ws.onerror = (err) => {
    console.error("WebSocket 错误: " + JSON.stringify(err));
  };

  ws.onclose = () => {
    console.info("WebSocket 已关闭");
  };
}

说明

  • onopen:连接成功回调。
  • onmessage:收到消息立刻更新 UI。
  • onerror / onclose:处理异常和断开。
  • 服务端可以随时推送数据,不需要客户端轮询。

QA 阶段

Q1:发布订阅和 DataAbility 有什么区别?

发布订阅更轻量,适合应用内事件;DataAbility 更像数据库,适合做数据共享和存储。

Q2:后台服务会不会被系统杀掉?

在 HarmonyOS 中,ServiceAbility 默认是后台长驻的,但如果内存紧张,系统也可能回收。可以通过合理的调度策略来增强存活率。

Q3:WebSocket 和轮询哪个好?

实时性要求高 → WebSocket;数据变化频率低且服务端不支持推送 → 定时轮询。

总结

鸿蒙应用实现实时数据更新,有多种方案可选:

  • 发布订阅:模块间解耦、事件驱动。
  • 后台服务:适合定时拉取或长时间运行的逻辑。
  • WebSocket:最适合实时推送场景。
  • DataAbility / DataBus:适合模块间或跨应用的数据共享。

开发中往往不是单一选择,而是组合使用。比如:消息系统用 WebSocket,配合事件分发到 UI;行情类数据用后台服务定时补偿,避免丢消息。

这样才能既保证实时性,又保证应用稳定。

相关推荐
AAA修煤气灶刘哥3 小时前
物联网-智能设备数据交互核心技术解析
物联网·华为
万少14 小时前
可可图片编辑 HarmonyOS 上架应用分享
前端·harmonyos
zhanshuo14 小时前
鸿蒙开发实战:掌握 Promise 和 async/await,轻松搞定异步请求
harmonyos
simple_lau20 小时前
H5资源包热更新:从下载、解压到渲染的实现方案
typescript·harmonyos·arkts
程序员二师兄20 小时前
记一次鸿蒙webview图片渲染失败的问题
前端·javascript·harmonyos
缘澄20 小时前
ArkTs声明式UI开发
harmonyos
大雷神1 天前
鸿蒙中应用框架和应用模型
华为·harmonyos
马剑威(威哥爱编程)1 天前
鸿蒙 NEXT开发中轻松实现人脸识别功能
华为·harmonyos·arkts·鸿蒙
张风捷特烈1 天前
鸿蒙纪·Flutter卷#03 | 从配置证书到打包发布
android·flutter·harmonyos