场景描述
在HarmonyOS开发中,事件通信是一种重要的通信手段,它支持同Ability、跨Ability、跨线程以及跨进程通信。当前提供的通信方式主要有Emitter、EventHub、CommonEvent,线程间通信也可以使用Worker和Taskpool提供的postMessage和sendData向数组线程发送消息。应用间通信可以使用自定义公共事件和IPC&RPC两种方式。
能力支持
- 同Ability通信:Emitter、EventHub、CommonEvent
- 跨Ability通信:Emitter、EventHub、CommonEvent
- 跨线程通信:Emitter、CommonEvent、Worker、Taskpool
- 跨进程通信:CommonEvent、IPC&RPC
方案描述
场景一:同Ability通信
通过Eventhub订阅事件打开自定义弹窗:
private uiAbilityContext = getContext() as common.UIAbilityContext;
aboutToAppear(): void {
this.uiAbilityContext.eventHub.on('openDialog', () => {
this.openDialog('自定义弹窗');
});
}
openDialog(str: string) {
let uiContext = this.getUIContext();
let promptAction = uiContext.getPromptAction();
let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), new Params(str));
promptAction.openCustomDialog(contentNode);
}
this.uiAbilityContext.eventHub.emit('openDialog');
this.uiAbilityContext.eventHub.off('openDialog');
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
场景二:跨Ability通信
使用EventHub进行数据通信:
private applicationContext = getContext().getApplicationContext();
eventFunc(arg: Dog) {
promptAction.showDialog({
'message': 'dog age is ' + arg.age
});
}
aboutToAppear(): void {
this.applicationContext.eventHub.on('myEvent', this.eventFunc);
}
@Observed
class Dog {
public age: number;
constructor(age: number) {
this.age = age;
}
}
this.applicationContext.eventHub.emit("myEvent", this.dog);
this.applicationContext.eventHub.off('myEvent');
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
场景三:线程间通信
使用Worker线程执行字符串倒序:
async executeWorkerFunc(inPutStr: string) {
if (!inPutStr.length) {
this.jsWorkerOutPutStr = "No input for the string to be reserved.\n";
return;
}
this.myWorker.postMessage(inPutStr);
let strFlag = false;
let outPutStr = '';
this.myWorker.onmessage = (e) => {
outPutStr = e.data.toString();
strFlag = true;
}
this.jsWorkerOutPutStr = outPutStr;
}
// worker.ets
let workerPort: ThreadWorkerGlobalScope = worker.workerPort;
workerPort.onmessage = (e: MessageEvents) => {
let oldData : string = e.data;
let newData = oldData.split("").reverse().join("");
workerPort.postMessage(newData);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
使用taskpool实现字符串排序:
emitter.on("eventId", (eventData: emitter.EventData) => {
promptAction.showToast({
message: 'receive' + eventData.data?.content,
duration: 2000
});
});
async executeImmediately() {
if (!this.taskPoolInPutStr.length) {
this.taskPoolOutPutStr = 'No input for the string to be sorted.\n';
return;
}
let task = new taskpool.Task(strSort, this.taskPoolInPutArr);
this.taskPoolStack.push(task);
await taskpool.execute(task).then((result) => {
this.taskPoolOutPutStr = `${this.taskPoolOutPutStr}Task executed successfully: ${result.toString()}`;
}).catch((e: Error) => {
this.taskPoolOutPutStr += `Task executed failed:${e.toString()}`;
});
this.taskPoolStack.pop();
}
function strSort(inPutArr: string[]): string[] {
let newArr = inPutArr.sort();
let eventData: emitter.EventData = {
data: {
'content': JSON.stringify(newArr),
}
};
emitter.emit('eventId', eventData);
return newArr;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
场景四:进程间通信
使用CommonEvent自定义公共事件:
// 发布方
let options: CommonEventManager.CommonEventPublishData = {
bundleName: 'com.example.mysubscriber',
};
CommonEventManager.publish('eventTest', options, (err: Base.BusinessError) => {
if (err) {
hilog.error(0xFF00, LOG_TAG, `PublishCallBack err = ${JSON.stringify(err)}`);
} else {
hilog.info(0xFF00, LOG_TAG, 'commonEvent Publish success');
}
});
// 订阅方
let subscriber: CommonEventManager.CommonEventSubscriber;
let subscribeInfo: CommonEventManager.CommonEventSubscribeInfo = {
events: ['eventTest'],
};
function SubscribeCB(err: Base.BusinessError, data: CommonEventManager.CommonEventData) {
if (err) {
hilog.error(0xFF00, LOG_TAG, `subscribe failed, code is ${err.code}, message is ${err.message}`);
} else {
publishNotification();
hilog.info(0xFF00, LOG_TAG, 'subscribe success');
}
}
function createCB(err: Base.BusinessError, commonEventSubscriber: CommonEventManager.CommonEventSubscriber) {
if (!err) {
hilog.info(0xFF00, LOG_TAG, 'createSubscriber');
subscriber = commonEventSubscriber;
CommonEventManager.subscribe(subscriber, SubscribeCB);
} else {
hilog.error(0xFF00, LOG_TAG, `createSubscriber failed, code is ${err.code}, message is ${err.message}`);
}
}
async function publishNotification() {
let wantAgent: _WantAgent;
let wantAgentInfo: WantAgent.WantAgentInfo = {
wants: [
{
bundleName: 'com.example.mysubscriber',
abilityName: 'EntryAbility',
} as Want
],
operationType: WantAgent.OperationType.START_ABILITIES,
requestCode: 0,
wantAgentFlags: [WantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
};
WantAgent.getWantAgent(wantAgentInfo).then((data) => {
wantAgent = data;
let notificationRequest: notificationManager.NotificationRequest = {
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: '自定义公共事件',
text: '收到其他应用一条消息',
additionalText: 'Test_AdditionalText',
},
},
id: 6,
tapDismissed: true,
notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,
label: 'Receive CommonEvent',
wantAgent: wantAgent,
};
notificationManager.publish(notificationRequest);
});
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
其它常见问题
- 粘性事件:HarmonyOS的Emitter不支持粘性事件,可以考虑使用自定义公共事件实现。
- 事件处理优先级:可以使用emitter定义事件优先级为idle,以确保低优先级任务不会阻塞主线程。