OpenHarmony系统应用之间的事件发送与订阅

4 阅读2分钟

在鸿蒙系统OpenHarmony中,可以通过事件的发布和订阅进行进程线程通信。
1,公共事件
公共事件类型定义在ohos.commonEventManager模块的Support枚举中。
公共事件包括诸如:
关机"usual.event.SHUTDOWN", 用户切换"usual.event.USER_SWITCHED", 锁屏"usual.event.SCREEN_LOCKED"等。可以通过订阅事件来监听。
@ohos.commonEventManager (公共事件模块)提供了公共事件相关的能力,包括发布公共事件、订阅公共事件、以及退订公共事件。
普通公共事件:只有当前已经订阅了该事件的接收者才能收到,事件发完就消失,后来订阅的收不到。普通事件发完即无。
粘性公共事件:事件发布后,系统会把它 “缓存” 下来;后续新订阅该事件的组件,即使事件已经发过,依然能收到最后一次的事件数据;一个事件名同一时间只会保留最新一条,新的粘性事件会覆盖旧的。粘性事件会被缓存。

若需发布粘性公共事件,需在 module.json5 中配置权限:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.COMMONEVENT_STICKY",
        "usedScene": {
          "ability": [],
          "when": "inuse"
        }
      }
    ]
  }
}

实现代码如下:

import commonEventManager from '@ohos.commonEventManager';
import Base from '@ohos.base';

export class HarmonyEventSubscribe {
  private static subscriber: commonEventManager.CommonEventSubscriber | null = null;

  static async startListenEvents(): Promise<void> {
    try {
      const subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
        events: [
          "usual.event.SHUTDOWN",
          "usual.event.USER_SWITCHED",
          "usual.event.SCREEN_LOCKED",
		  ...
        ]
      };

      HarmonyEventSubscribe.subscriber = await commonEventManager.createSubscriber(subscribeInfo);
      commonEventManager.subscribe(HarmonyEventSubscribe.subscriber, (err: Base.BusinessError, data: commonEventManager.CommonEventData) => {
        if (err) {
          return;
        }
        const event = data.event;
        Log.i(TAG + " received event:" + event);

        this.handleSystemEvent(event);
      });

    } catch (err) {
      Log.e(TAG + " scribed failed:" + JSON.stringify(err));
    }
  }

  private static async handleSystemEvent(event: string) {
    switch (event) {
      case "usual.event.SHUTDOWN":
        Log.i(TAG + ">>> SHUTDOWN");
        break;

      case "usual.event.USER_SWITCHED":
        Log.i(TAG + ">>> USER_SWITCHED");
        break;
      case "usual.event.SCREEN_LOCKED":
        Log.i(TAG + ">>> SCREEN_LOCKED");
        break;
    }
  }

  static stopListenEvents(): void {
    if (HarmonyEventSubscribe.subscriber) {
      commonEventManager.unsubscribe(HarmonyEventSubscribe.subscriber);
      HarmonyEventSubscribe.subscriber = null;
    }
  }
}

上面的代码在export default class EntryAbility extends UIAbility{}中的onCreate和onDestrory函数中调用即可。

2,自定义事件
以在一个第三方系统应用控制锁屏为例进行阐述。在鸿蒙系统OpenHarmony中,锁屏是由com.ohos.systemui下的SystemUI-ScreenLock.hap文件完成相关的锁屏功能。
实现代码如下:

import commonEventManager from '@ohos.commonEventManager';

triggerUserEvent(): void {
    try {
      let publishData: commonEventManager.CommonEventPublishData = {
        bundleName: "com.ohos.systemui", // 指定接收方包名,只有该包名的应用才能接收到事件
        isOrdered: false,
        data: "",
        parameters: {
			"lsInterval": 60
		},
        code: 0
      };
      commonEventManager.publish('com.ohos.eric.user_event', publishData, (err) => {
        if (err) {
          Log.e(`publish user event error: ${JSON.stringify(err)}`);
        } else {
          Log.i(`publish user event success`);
        }
      })
    } catch (error) {
      Log.e(`trigger user event error: ${JSON.stringify(error)}`);
    }
}

发出自定义事件后,screenlock应用接收事件。 实现代码如下:

import commonEventManager from '@ohos.commonEventManager';

export class ScreenLockService {
	private lsSubscriber: commonEventManager.CommonEventSubscriber | null = null;
        private lsInterval: string;
	init() {
		this.subscribeUserEvent();
	}
	
	private subscribeUserEvent() {
        let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
            events: ['com.ohos.eric.user_event']
        };
        commonEventManager.createSubscriber(subscribeInfo, (err, subscriber) => {
            if (err) {
                return;
            }
            this.lsSubscriber = subscriber;
            commonEventManager.subscribe(subscriber, (err, data) => {
                Log.i(TAG, `received user event: ${JSON.stringify(data)}`);
                if (err) {
                    return;
                }
                this.lsInterval = data.parameters.lsInterval;
                this.lockScreen();
            });
        });
    }
	
	private unsubscribeUserEvent() {
        if (this.lsSubscriber) {
            try {
                commonEventManager.unsubscribe(this.lsSubscriber);
                Log.i(TAG, `unsubscribe user event success`);
                this.lsSubscriber = null;
            } catch (err) {
                Log.e(TAG, `unsubscribe user event failed: ${JSON.stringify(err)}`);
            }
        }
    }
}