摘要
在當下的應用開發中,用戶體驗越來越依賴“實時性”。消息要第一時間送達、訂單狀態要立刻刷新、數據變化不能延遲……這些需求推動了“實時數據更新”成為應用的必備功能。在鴻蒙系統(HarmonyOS)中,我們既可以用系統內置的數據能力(DataAbility、DataBus),也可以用事件驅動(發布訂閱)、后臺服務,甚至和遠程服務器保持 WebSocket 長連接。不同的方案適合不同的場景,本文會帶大家從原理到實戰,結合代碼一步步拆解。
引言
假設你正在做一個電商應用:用戶提交訂單后希望能立刻看到訂單狀態更新;商家端改價后,用戶端價格立刻刷新;再比如做一個股票類 App,行情數據需要秒級同步。這類場景在鴻蒙中都可以實現。
那怎么做呢?常見的方式包括:
- DataAbility:適合模塊內、應用間的數據共享和通知。
- 發布-訂閱(Publish-Subscribe):輕量、解耦,常用在組件交互。
- 后臺服務(ServiceAbility):適合長期任務,比如輪詢服務器。
- WebSocket:和后端保持實時通信。
- DataBus:模塊間的消息和數據同步。
接下來,我們用幾個實際場景來展開。
用發布-訂閱實現應用內實時更新
發布-訂閱是應用內實時通知最常見的方式,模塊之間不用直接耦合,只要關心“訂閱什么事件”和“發布什么事件”即可。
場景:聊天應用消息刷新
用戶在 A 頁面發了一條消息,B 頁面需要立刻刷新列表。
這時可以用事件分發,避免兩個頁面硬編碼依賴。
Demo 代碼
// 定義一個事件 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);
}
// 訂閱者(比如消息列表頁面)
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 代碼
// 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);// 推送事件給 UIeventEmitter.emit({ eventId: 2, eventName: "stock_price_update" }, {data: { price }});}, 5000); // 每 5 秒刷新一次}
}
// 前臺頁面訂閱股價更新
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 代碼
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;行情類數據用后臺服務定時補償,避免丟消息。
這樣才能既保證實時性,又保證應用穩定。