Openharmony IPC通信(L2)
原創??https://harmonyos.51cto.com??
一、簡介
Openharmony的IPC通信,幾乎所有模塊都有用到。
對IPC通信流程的理解,為熟悉了解其他模塊有很重要的幫助。
IPC通信(倉庫:communication_ipc)與safwk系統服務框架(倉庫:distributedschedule_safwk)和samgr系統服務管理(倉庫:distributedschedule_samgr)有很緊密的聯系。
二、IPC通信
2.1 IPC通信注冊流程
以foundation\communication\ipc\ipc\test\auxiliary\native為例,對IPC進行梳理。
IPC通信包括客戶端(client)和服務端(service)。
- 服務端TestService繼承自IPCObjectStub。
- 客戶端TestServiceClient通過iface_cast(object)獲取到一個TestServiceProxy對象。TestServiceProxy繼承自PeerHolder,里面包含指向IPCObjectProxy的指針。
- 客戶端的IPCObjectProxy和服務端IPCObjectStub是對應關系。
流程圖:
流程圖解釋
服務端以IPC_TEST_SERVICE為saId,將繼承自IPCObjectStub的對象經dbinder驅動,注冊到samgr系統服務管理進程中去。
binder_translate_binder有一個將標志為BINDER_TYPE_BINDER轉換成BINDER_TYPE_HANDLE的過程。samgr響應注冊消息,通過BinderInvoker::UnflattenObject解析對象,實際上是根據注冊的IPCObjectStubnew一個IPCObjectProxy對象存儲在samgr的map中。
客戶端以IPC_TEST_SERVICE去samgr中取IPCObjectProxy對象。并通過iface_castnew一個包含取的IPCObjectProxy的TestServiceProxy對象。這樣客戶端和服務端就建立起了關系,可以進行下一步相互通信。
2.2 IPC通信交互
Openharmony的IPC通信,有點類似http協議:客戶發送數據==>服務端響應處理數據==>服務端回復==>客戶端獲取到回復數據
流程圖如下:
客戶端與服務端的交互
客戶端通過: Remote()->SendRequest向服務端發消息,等待結果。
服務端通過: xxxServiceStub::OnRemoteRequest處理客戶端消息,并回復。
三、samgr系統服務管理進程
主要管理各個模塊服務端注冊的saId和IPCObjectProxy對象鍵值對。
四、safwk系統服務框架
IPC客戶端服務端注冊拉起框架。
4.1 服務端的注冊
xxxInterface是客戶端和服務端都需要實現的接口繼承類。
注冊方式1,基本上自己有main函數入口:
xxxService繼承IPCObjectStub 和 xxxInterface
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> newInstance = new xxxService();
int result = saMgr->AddSystemAbility(xxxSaId, newInstance);
注冊方式2, 本身沒有main函數入口,需要借助safwk的main入口:
xxxService繼承IPCObjectStub,xxxInterface 和 SystemAbility
// 注冊方式2的第一種方式
REGISTER_SYSTEM_ABILITY_BY_ID(xxxService, xxxSaId, true);
// 注冊方式2的第二種方式
SystemAbility::MakeAndRegisterAbility
4.2 服務拉起
- 注冊方式1:有main入口,是一個獨立進程。直接運行即可。
- 注冊方式2:編譯出來是一個動態庫,
通過: /system/bin/sa_main /system/profile/xxx_sa.xml拉起來,xml文件中配置了動態庫信息。可以參考文檔
??【OpenHarmony SA 動態庫服務 拉起的main入口】??了解拉起流程
4.3 客戶端類定義
xxxServiceProxy繼承PeerHolder 和 xxxInterface
客戶端類中定義一個靜態變量:
// 定義靜態變量,才能通過iface_cast創建一個包含IPCObjectProxy的xxxServiceProxy對象
static inline BrokerDelegator<xxxServiceProxy> delegator_;
4.4 客戶端獲取注冊信息
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> object = saMgr->GetSystemAbility(SaId);
client = iface_cast<xxxInterface >(object);
以foundation\communication\ipc\ipc\test\auxiliary\native為例繼承圖:
??https://harmonyos.51cto.com??