HarmonyOS遠端狀態訂閱開發例項
IPC/RPC提供對遠端Stub物件狀態的訂閱機制, 在遠端Stub物件消亡時,可觸發消亡通知告訴本地Proxy物件。這種狀態通知訂閱需要呼叫特定介面完成,當不再需要訂閱時也需要呼叫特定介面取消。使用這種訂閱機制的使用者,需要實現消亡通知介面DeathRecipient並實現onRemoteDied方法清理資源。該方法會在遠端Stub物件所在程式消亡或所在裝置離開組網時被回撥。值得注意的是,呼叫這些介面有一定的順序。首先,需要Proxy訂閱Stub消亡通知,若在訂閱期間Stub狀態正常,則在不再需要時取消訂閱;若在訂閱期間Stub所在程式退出或者所在裝置退出組網,則會自動觸發Proxy自定義的後續操作。
使用場景
這種訂閱機制適用於本地Proxy物件需要感知遠端Stub物件所在程式消亡,或所在裝置離開組網的場景。當Proxy感知到Stub端消亡後,可適當清理本地資源。此外,RPC目前不提供匿名Stub物件的消亡通知,即只有向SAMgr註冊過的服務才能被訂閱消亡通知,IPC則支援匿名物件的消亡通知。
Native側介面
介面名 |
返回值型別 |
功能描述 |
AddDeathRecipient(const sptr<DeathRecipient> &recipient); |
bool |
訂閱遠端Stub物件狀態。 |
RemoveDeathRecipient(const sptr<DeathRecipient> &recipient); |
bool |
取消訂閱遠端Stub物件狀態。 |
OnRemoteDied(const wptr<IRemoteObject> &object); |
void |
當遠端Stub物件死亡時回撥。 |
參考程式碼
#include "iremote_broker.h" #include "iremote_stub.h" //定義訊息碼 enum { TRANS_ID_PING_ABILITY = 5, TRANS_ID_REVERSED_MONITOR }; const std::string DESCRIPTOR = "test.ITestAbility"; class ITestService : public IRemoteBroker { public: // DECLARE_INTERFACE_DESCRIPTOR是必需的,入參需使用std::u16string; DECLARE_INTERFACE_DESCRIPTOR(to_utf16(DESCRIPTOR)); virtual int TestPingAbility(const std::u16string &dummy) = 0; // 定義業務函式 }; class TestServiceProxy : public IRemoteProxy<ITestAbility> { public: explicit TestAbilityProxy(const sptr<IRemoteObject> &impl); virtual int TestPingAbility(const std::u16string &dummy) override; int TestAnonymousStub(); private: static inline BrokerDelegator<TestAbilityProxy> delegator_; // 方便後續使用iface_cast宏 }; TestServiceProxy::TestServiceProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<ITestAbility>(impl) { } int TestServiceProxy::TestPingAbility(const std::u16string &dummy){ MessageOption option; MessageParcel dataParcel, replyParcel; dataParcel.WriteString16(dummy); int error = PeerHolder::Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option); int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1; return result; }
#include "iremote_object.h" class TestDeathRecipient : public IRemoteObject::DeathRecipient { public: virtual void OnRemoteDied(const wptr<IRemoteObject>& remoteObject); } void TestDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remoteObject) { }
sptr<IPCObjectProxy> object = new IPCObjectProxy(1, to_utf16(DESCRIPTOR)); sptr<IRemoteObject::DeathRecipient> deathRecipient (new TestDeathRecipient());// 構造一個消亡通知物件 bool result = object->AddDeathRecipient(deathRecipient); // 註冊消亡通知 result = object->RemoveDeathRecipient(deathRecipient); // 移除消亡通知
JS側介面
介面名 |
返回值型別 |
功能描述 |
addDeathRecipient |
boolean |
註冊用於接收遠端物件消亡通知的回撥,增加proxy物件上的消亡通知。 |
removeDeathRecipient |
boolean |
登出用於接收遠端物件消亡通知的回撥。 |
onRemoteDied |
void |
在成功新增死亡通知訂閱後,當遠端物件死亡時,將自動呼叫本方法。 |
參考程式碼
import FA from "@ohos.ability.featureAbility"; let proxy; let connect = { onConnect: function(elementName, remoteProxy) { console.log("RpcClient: js onConnect called."); proxy = remoteProxy; }, onDisconnect: function(elementName) { console.log("RpcClient: onDisconnect"); }, onFailed: function() { console.log("RpcClient: onFailed"); } }; let want = { "bundleName": "com.ohos.server", "abilityName": "com.ohos.server.MainAbility", }; FA.connectAbility(want, connect); class MyDeathRecipient { onRemoteDied() { console.log("server died"); } } let deathRecipient = new MyDeathRecipient(); proxy.addDeathRecipient(deathRecipient, 0); proxy.removeDeathRecipient(deathRecipient, 0);
Stub感知Proxy消亡(匿名Stub的使用)
正向的消亡通知是Proxy感知Stub的狀態,若想達到反向的死消亡通知,即Stub感知Proxy的狀態,可以巧妙的利用正向消亡通知。如兩個程式A(原Stub所在程式)和B(原Proxy所在程式),程式B在獲取到程式A的Proxy物件後,在B程式新建一個匿名Stub物件(匿名指未向SAMgr註冊),可稱之為回撥Stub,再透過SendRequest介面將回撥Stub傳給程式A的原Stub。這樣一來,程式A便獲取到了程式B的回撥Proxy。當程式B消亡或B所在裝置離開組網時,回撥Stub會消亡,回撥Proxy會感知,進而通知給原Stub,便實現了反向消亡通知。
注意:
反向死亡通知僅限裝置內跨程式通訊使用,不可用於跨裝置。
當匿名Stub物件沒有被任何一個Proxy指向的時候,核心會自動回收。
參考程式碼
//Proxy int TestAbilityProxy::TestAnonymousStub() { MessageOption option; MessageParcel dataParcel, replyParcel; dataParcel.UpdateDataVersion(Remote()); dataParcel.WriteRemoteObject(new TestAbilityStub()); int error = Remote()->SendRequest(TRANS_ID_REVERSED_MONITOR,dataParcel, replyParcel, option); int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1; return result; } //Stub int TestAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { switch (code) { case TRANS_ID_REVERSED_MONITOR: { sptr<IRemoteObject> obj = data.ReadRemoteObject(); if (obj == nullptr) { reply.WriteInt32(ERR_NULL_OBJECT); return ERR_NULL_OBJECT; } bool result = obj->AddDeathRecipient(new TestDeathRecipient()); result ? reply.WriteInt32(ERR_NONE) : reply.WriteInt32(-1); break; } default: break; } return ERR_NONE; }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009402/viewspace-2988536/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 鴻蒙IPC Kit遠端狀態訂閱:程序消亡時的資源管理機制鴻蒙
- 遠端開發分散式C#程式設計例項分散式C#程式設計
- C# 中 釋出訂閱例項C#
- HarmonyOS開發例項:【相機和媒體庫】
- 3.1.5.9 啟動遠端例項
- java狀態模式例項解析Java模式
- javascript訂閱模式淺析和基礎例項JavaScript模式
- 遠端客戶端 訪問 ASM 例項客戶端ASM
- Java MQTT訂閱端,可訂閱萬用字元(/#)JavaMQQT字元
- oracle資料庫例項狀態Oracle資料庫
- BCB 客戶端 tuxedo 開發例項客戶端UX
- bbossaop遠端服務介紹-遠端服務呼叫例項
- HarmonyOS NEXT應用開發案例—狀態列顯隱變化
- BCB 客戶端 tuxedo 開發例項 (轉)客戶端UX
- CSS載入遠端字型例項程式碼CSS
- Python實現遠端埠監控例項Python
- mysql例項停止、啟動、配置遠端訪問MySql
- 資料庫訂單狀態資料庫
- Linux遠端開發Linux
- 訂閱號服務開發01-搭建開發環境開發環境
- 達夢資料庫例項的狀態和模式資料庫模式
- HarmonyOS-基礎之狀態資料共享
- mysql設定指定ip遠端訪問連線例項MySql
- iOS開發之遠端推送iOS
- css設定連結a的狀態的例項程式碼CSS
- 5 個開源 RSS 訂閱閱讀器
- HarmonyOS UI 開發UI
- 【Oracle ASM】關於asm例項與db例項中的磁碟狀態_詳細分析過程OracleASM
- HarmonyOS 實踐之應用狀態變數共享變數
- 鴻蒙HarmonyOS實戰-ArkTS語言(狀態管理)鴻蒙
- 通過SQL*Plus遠端啟動Oracle資料庫例項SQLOracle資料庫
- C#開發例項大全C#
- angular模組庫開發例項Angular
- jquery外掛開發例項jQuery
- ABAP 報表開發例項
- 論文閱讀 狀態壓縮
- UX設計之——按鈕使用例項、型別和狀態UX型別
- VScode 遠端開發配置VSCode