HarmonyOS學(xué)習(xí)路之開發(fā)篇—公共事件與通知(一)
1
公共事件與通知開發(fā)概述
HarmonyOS通過CES(Common Event Service,公共事件服務(wù))為應(yīng)用程序提供訂閱、發(fā)布、退訂公共事件的能力,通過ANS(Advanced Notification Service,即通知增強(qiáng)服務(wù))系統(tǒng)服務(wù)來為應(yīng)用程序提供發(fā)布通知的能力。
公共事件可分為系統(tǒng)公共事件和自定義公共事件。 系統(tǒng)公共事件:系統(tǒng)將收集到的事件信息,根據(jù)系統(tǒng)策略發(fā)送給訂閱該事件的用戶程序。例如:用戶可感知亮滅屏事件,系統(tǒng)關(guān)鍵服務(wù)發(fā)布的系統(tǒng)事件(例如:USB插拔,網(wǎng)絡(luò)連接,系統(tǒng)升級等)。 自定義公共事件:應(yīng)用自定義一些公共事件用來處理業(yè)務(wù)邏輯。 通知提供應(yīng)用的即時消息或通信消息,用戶可以直接刪除或點擊通知觸發(fā)進(jìn)一步的操作。 IntentAgent封裝了一個指定行為的Intent,可以通過IntentAgent啟動Ability和發(fā)布公共事件。
應(yīng)用如果需要接收公共事件,需要訂閱相應(yīng)的事件。
2
公共事件開發(fā)
接口說明
公共事件相關(guān)基礎(chǔ)類包含CommonEventData、CommonEventPublishInfo、CommonEventSubscribeInfo、CommonEventSubscriber和CommonEventManager?;A(chǔ)類之間的關(guān)系如下圖所示:
圖1 公共事件基礎(chǔ)類關(guān)系圖
CommonEventData
CommonEventData封裝公共事件相關(guān)信息。用于在發(fā)布、分發(fā)和接收時處理數(shù)據(jù)。在構(gòu)造CommonEventData對象時,相關(guān)參數(shù)需要注意以下事項:
code為有序公共事件的結(jié)果碼,data為有序公共事件的結(jié)果數(shù)據(jù),僅用于有序公共事件場景。 intent不允許為空,否則發(fā)布公共事件失敗。
CommonEventPublishInfo
CommonEventPublishInfo封裝公共事件發(fā)布相關(guān)屬性、限制等信息,包括公共事件類型(有序或粘性)、接收者權(quán)限等。
有序公共事件:主要場景是多個訂閱者有依賴關(guān)系或者對處理順序有要求,例如:高優(yōu)先級訂閱者可修改公共事件內(nèi)容或處理結(jié)果,包括終止公共事件處理;或者低優(yōu)先級訂閱者依賴高優(yōu)先級的處理結(jié)果等。 粘性公共事件:指公共事件的訂閱動作是在公共事件發(fā)布之后進(jìn)行,訂閱者也能收到的公共事件類型。主要場景是由公共事件服務(wù)記錄某些系統(tǒng)狀態(tài),如藍(lán)牙、WLAN、充電等事件和狀態(tài)。CommonEventSubscribeInfoCommonEventSubscribeInfo封裝公共事件訂閱相關(guān)信息,比如優(yōu)先級、線程模式、事件范圍等。線程模式(ThreadMode):設(shè)置訂閱者的回調(diào)方法執(zhí)行的線程模式。ThreadMode有HANDLER,POST,ASYNC, BACKGROUND四種模式,目前只支持HANDLER模式。 HANDLER:在Ability的主線程上執(zhí)行。 POST:在事件分發(fā)線程執(zhí)行。 ASYNC:在一個新創(chuàng)建的異步線程執(zhí)行。 BACKGROUND:在后臺線程執(zhí)行。
CommonEventSubscriber
CommonEventSubscriber封裝公共事件訂閱者及相關(guān)參數(shù)。
CommonEventSubscriber.AsyncCommonEventResult類處理有序公共事件異步執(zhí)行。 目前只能通過調(diào)用CommonEventManagersubscribeCommonEvent()進(jìn)行訂閱。
CommonEventManager
CommonEventManager是為應(yīng)用提供訂閱、退訂和發(fā)布公共事件的靜態(tài)接口類。
3
Demo實例程序
效果演示如下所示:
4
發(fā)布公共事件
四種公共事件:無序的公共事件、帶權(quán)限的公共事件、有序的公共事件、粘性的公共事件。
發(fā)布無序的公共事件:構(gòu)造CommonEventData對象,設(shè)置Intent,通過構(gòu)造operation對象把需要發(fā)布的公共事件信息傳入intent對象。然后調(diào)用 CommonEventManager.publishCommonEvent(CommonEventData) 接口發(fā)布公共事件。
public void publishDisorderedEvent() {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withAction(event).build();
intent.setOperation(operation);
CommonEventData eventData = new CommonEventData(intent);
try {
CommonEventManager.publishCommonEvent(eventData);
showTips(context, "Publish succeeded");
} catch (RemoteException e) {
HiLog.error(LABEL_LOG, "%{public}s", "publishDisorderedEvent remoteException.");
}
}
發(fā)布攜帶權(quán)限的公共事件:構(gòu)造CommonEventPublishInfo對象,設(shè)置訂閱者的權(quán)限。
在config.json中申請所需的權(quán)限
"reqPermissions": [
{
"name": "ohos.samples.permission",
"reason": "get right",
"usedScene": {
"ability": [
".MainAbilitySlice"
],
"when": "inuse"
}
}
]
發(fā)布帶權(quán)限的公共事件示例代碼如下
public void publishPermissionEvent() {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withAction(event).build();
intent.setOperation(operation);
CommonEventData eventData = new CommonEventData(intent);
CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
String[] permissions = {"ohos.sample.permission"};
publishInfo.setSubscriberPermissions(permissions);
try {
CommonEventManager.publishCommonEvent(eventData, publishInfo);
showTips(context, "Publish succeeded");
} catch (RemoteException e) {
HiLog.error(LABEL_LOG, "%{public}s", "publishPermissionEvent remoteException.");
}
}
發(fā)布有序的公共事件:構(gòu)造CommonEventPublishInfo對象,通過setOrdered(true)指定公共事件屬性為有序公共事件,也可以指定一個最后的公共事件接收者。
public void publishOrderlyEvent() {
MatchingSkills skills = new MatchingSkills();
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withAction(event).build();
intent.setOperation(operation);
CommonEventData eventData = new CommonEventData(intent);
skills.addEvent(event);
CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
publishInfo.setOrdered(true);
try {
CommonEventManager.publishCommonEvent(eventData, publishInfo);
showTips(context, "Publish succeeded");
} catch (RemoteException e) {
HiLog.error(LABEL_LOG, "%{public}s", "publishOrderlyEvent remoteException.");
}
}
發(fā)布粘性公共事件:構(gòu)造CommonEventPublishInfo對象,通過setSticky(true)指定公共事件屬性為粘性公共事件。
發(fā)布者首先在config.json中申請發(fā)布粘性公共事件所需的權(quán)限
"reqPermissions": [
{
"name": "ohos.permission.COMMONEVENT_STICKY",
"reason": "get right",
"usedScene": {
"ability": [
".MainAbilitySlice"
],
"when": "inuse"
}
}
]
發(fā)布粘性公共事件
public void publishStickyEvent() {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withAction(event).build();
intent.setOperation(operation);
CommonEventData eventData = new CommonEventData(intent);
CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
publishInfo.setSticky(true);
try {
CommonEventManager.publishCommonEvent(eventData, publishInfo);
showTips(context, "Publish succeeded");
} catch (RemoteException e) {
HiLog.error(LABEL_LOG, "%{public}s", "publishStickyEvent remoteException.");
}
}
5
訂閱公共事件
1、創(chuàng)建CommonEventSubscriber派生類,在onReceiveEvent()回調(diào)函數(shù)中處理公共事件。
class TestCommonEventSubscriber extends CommonEventSubscriber {
TestCommonEventSubscriber(CommonEventSubscribeInfo info) {
super(info);
}
@Override
public void onReceiveEvent(CommonEventData commonEventData) {
}
}
2、構(gòu)造MyCommonEventSubscriber對象,調(diào)用CommonEventManager.subscribeCommonEvent()接口進(jìn)行訂閱。
String event = "測試";
MatchingSkills matchingSkills = new MatchingSkills();
matchingSkills.addEvent(event); // 自定義事件
CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
TestCommonEventSubscribersubscriber = new TestCommonEventSubscriber(subscribeInfo);
try {
CommonEventManager.subscribeCommonEvent(subscriber);
} catch (RemoteException e) {
HiLog.error(LABEL, "Exception occurred during subscribeCommonEvent invocation.");
}
如果訂閱的公共事件是有序的,可以調(diào)用setPriority()指定優(yōu)先級。
String event = "測試";
MatchingSkills matchingSkills = new MatchingSkills();
matchingSkills.addEvent(event); // 自定義事件
CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
subscribeInfo.setPriority(100); // 設(shè)置優(yōu)先級,優(yōu)先級取值范圍[-1000,1000],值默認(rèn)為0。
TestCommonEventSubscribersubscriber subscriber = new TestCommonEventSubscribersubscriber (subscribeInfo);
try {
CommonEventManager.subscribeCommonEvent(subscriber);
} catch (RemoteException e) {
HiLog.error(LABEL, "Exception occurred during subscribeCommonEvent invocation.");
}
3、針對在onReceiveEvent中不能執(zhí)行耗時操作的限制,可以使用CommonEventSubscriber的goAsyncCommonEvent()來實現(xiàn)異步操作,函數(shù)返回后仍保持該公共事件活躍,且執(zhí)行完成后必須調(diào)用AsyncCommonEventResult .finishCommonEvent()來結(jié)束。
EventRunner runner = EventRunner.create(); // EventRunner創(chuàng)建新線程,將耗時的操作放到新的線程上執(zhí)行
MyEventHandler myHandler = new MyEventHandler(runner); // MyEventHandler為EventHandler的派生類,在不同線程間分發(fā)和處理事件和Runnable任務(wù)
@Override
public void onReceiveEvent(CommonEventData commonEventData){
final AsyncCommonEventResult result = goAsyncCommonEvent();
Runnable task = new Runnable() {
@Override
public void run() {
........ // 待執(zhí)行的操作,由開發(fā)者定義
result.finishCommonEvent(); // 調(diào)用finish結(jié)束異步操作
}
};
myHandler.postTask(task);
}
6
退訂公共事件
在Ability的onStop()中調(diào)用CommonEventManager.unsubscribeCommonEvent()方法來退訂公共事件。調(diào)用后,之前訂閱的所有公共事件均被退訂。
public void unSubscribeEvent() {
if (subscriber == null) {
HiLog.info(LABEL_LOG, "%{public}s", "CommonEvent onUnsubscribe commonEventSubscriber is null");
return;
}
try {
CommonEventManager.unsubscribeCommonEvent(subscriber);
showTips(context, "UnSubscribe succeeded");
} catch (RemoteException e) {
HiLog.error(LABEL_LOG, "%{public}s", "unsubscribeEvent remoteException.");
}
destroy();
}
private void destroy() {
subscriber = null;
eventListener = null;
unSubscribe = true;
}
往期推薦

