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;行情类数据用后台服务定时补偿,避免丢消息。

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

2025-11-07 11:55:59