HarmonyOS學(xué)習(xí)路之開發(fā)篇——公共事件與通知(一)

公共事件與通知開發(fā)概述

HarmonyOS通過CES(Common Event Service,公共事件服務(wù))為應(yīng)用程序提供訂閱、發(fā)布、退訂公共事件的能力,通過ANS(Advanced Notification Service,即通知增強服務(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ā)進一步的操作。
  • IntentAgent封裝了一個指定行為的Intent,可以通過IntentAgent啟動Ability和發(fā)布公共事件。

應(yīng)用如果需要接收公共事件,需要訂閱相應(yīng)的事件。

公共事件開發(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ā)布之后進行,訂閱者也能收到的公共事件類型。主要場景是由公共事件服務(wù)記錄某些系統(tǒng)狀態(tài),如藍牙、WLAN、充電等事件和狀態(tài)。
    CommonEventSubscribeInfo
    CommonEventSubscribeInfo封裝公共事件訂閱相關(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()進行訂閱。

CommonEventManager
CommonEventManager是為應(yīng)用提供訂閱、退訂和發(fā)布公共事件的靜態(tài)接口類。

Demo實例程序

效果演示
https://live.csdn.net/v/167732

發(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.");
        }
    }

訂閱公共事件

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()接口進行訂閱。

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);
} 

退訂公共事件

在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;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容