HarmonyOS Sample 之 ServiceAbility 跨設(shè)備接口調(diào)用
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
ServiceAbility 跨設(shè)備接口調(diào)用
介紹
本示例演示了Service Ability的啟動(dòng)、停止、連接、斷開連接等操作,支持對(duì)跨設(shè)備的Service Ability進(jìn)行操作。
你將學(xué)會(huì)以下三個(gè)知識(shí)點(diǎn):
1.IDL的使用,以及IPC方法的調(diào)用
2.前臺(tái)Service的使用方法
3.EventHandle事件處理的使用方法
搭建環(huán)境
安裝DevEco Studio,詳情請(qǐng)參考DevEco Studio下載。
設(shè)置DevEco Studio開發(fā)環(huán)境,DevEco Studio開發(fā)環(huán)境需要依賴于網(wǎng)絡(luò)環(huán)境,需要連接上網(wǎng)絡(luò)才能確保工具的正常使用,可以根據(jù)如下兩種情況來配置開發(fā)環(huán)境:
- 如果可以直接訪問Internet,只需進(jìn)行下載HarmonyOS SDK操作。
- 如果網(wǎng)絡(luò)不能直接訪問Internet,需要通過代理服務(wù)器才可以訪問,請(qǐng)參考配置開發(fā)環(huán)境。
代碼結(jié)構(gòu)解讀
后臺(tái)邏輯
- │ config.json #全局配置文件
- │
- ├─idl
- │ └─ohos
- │ └─samples
- │ └─serviceability
- │ IRemoteAgent.idl #提供遠(yuǎn)程接口idl文件
- │
- ├─java
- │ └─ohos
- │ └─samples
- │ └─serviceability
- │ │ ForegroundServiceAbility.java #前臺(tái)Service Ability
- │ │ LocalServiceAbility.java #模擬本地的Service Ability
- │ │ MainAbility.java
- │ │ RemoteAbility.java #模擬遠(yuǎn)端的Service Ability
- │ │
- │ └─slice
- │ MainAbilitySlice.java #主能力頁
頁面布局文件只有一個(gè) main_slice.xml
頁面布局
三個(gè)知識(shí)點(diǎn)
1.IDL的使用,以及IPC方法的調(diào)用
術(shù)語:
當(dāng)客戶端和服務(wù)器通信時(shí),需要定義雙方都認(rèn)可的接口,以保障雙方可以成功通信,HarmonyOS IDL(HarmonyOS Interface Definition Language)則是一種定義此類接口的工具。
跨進(jìn)程調(diào)用(IPC)inter-process communication 或 跨設(shè)備調(diào)用(RPC)remote procedure call
IDL接口使用規(guī)范:
https://developer.harmonyos.com/cn/docs/documentation/doc-references/idl-overview-0000001050762835
先聲明權(quán)限,同時(shí)敏感權(quán)限還需要請(qǐng)求用戶授權(quán),前幾篇都有寫過這里就不寫了。
- "reqPermissions": [
- {
- "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
- },
- ...
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ]
a.創(chuàng)建.idl文件

IRemoteAgent.idl
- // Declare any non-default types here with sequenceable or interface statements
- interface ohos.samples.serviceability.IRemoteAgent {
- /*
- * Demo service method use some parameters
- */
- void setRemoteObject([in] String param);
- }
b.編譯idl文件,生成對(duì)應(yīng)的接口類、樁類和代理類


c.服務(wù)端IDL的實(shí)現(xiàn)
- private static final String DESCRIPTOR = "ohos.samples.serviceability.RemoteAbility";
- //idl的服務(wù)端實(shí)現(xiàn),
- RemoteAgentStub remoteAgentStub = new RemoteAgentStub(DESCRIPTOR) {
- @Override
- public void setRemoteObject(String param) {
- HiLog.info(LABEL_LOG, "%{public}s", "setRemoteObject:"+param);
- //不能這樣,要用下面通知的方式
- //showTips(RemoteAbility.this, param);
- //賦值
- param_mess=param;
- //事件通知
- eventHandler.sendEvent(EVENT_ABILITY_MESS);
- }
- };
d.客戶端調(diào)用IPC方法
- //IDL代理類
- private RemoteAgentProxy remoteAgentProxy;
- /**
- * 連接 Service
- * @param isConnectRemote
- */
- private void connectService(boolean isConnectRemote) {
- //三元表達(dá)式,判斷連接本地還是遠(yuǎn)端Service
- Intent intent = isConnectRemote
- ? getRemoteServiceIntent(REMOTE_BUNDLE, REMOTE_SERVICE)
- : getLocalServiceIntent(LOCAL_BUNDLE, NORMAL_SERVICE);
- //連接 Service
- boolean isConnect=connectAbility(intent,connection);
- if (isConnect && remoteAgentProxy!=null) {
- try {
- //調(diào)用服務(wù)端IPC方法
- remoteAgentProxy.setRemoteObject("This param from client");
- } catch (RemoteException e) {
- HiLog.error(LABEL_LOG, "%{public}s", "onAbilityConnectDone RemoteException");
- }
- }
- }
- //建立連接,實(shí)例化代理對(duì)象
- private IAbilityConnection connection = new IAbilityConnection() {
- @Override
- public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) {
- //發(fā)個(gè)通知,Service 連接成功了
- eventHandler.sendEvent(EVENT_ABILITY_CONNECT_DONE);
- //實(shí)例化代理對(duì)象
- remoteAgentProxy = new RemoteAgentProxy(iRemoteObject);
- }
- @Override
- public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
- //發(fā)個(gè)通知,Service 斷開連接了,主動(dòng)斷開不會(huì)執(zhí)行,關(guān)閉服務(wù)端會(huì)執(zhí)行
- eventHandler.sendEvent(EVENT_ABILITY_DISCONNECT_DONE);
- }
- };
2.前臺(tái)Service的使用方法
a.權(quán)限聲明:
- "reqPermissions": [
- {
- "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
- },
- ...
- ]
b.設(shè)置通知欄內(nèi)容,然后,
- 在onStart方法調(diào)用keepBackgroundRunning方法在后臺(tái)保留此服務(wù)能力并顯示通知欄。
- 在onStop方法調(diào)用cancelBackgroundRunning()方法取消此功能的后臺(tái)運(yùn)行以釋放系統(tǒng)內(nèi)存。
- //通知ID
- private static final int NOTIFICATION_ID = 0XD0000002;
- @Override
- protected void onStart(Intent intent) {
- //調(diào)用方法
- startForeground();
- super.onStart(intent);
- }
- @Override
- protected void onStop() {
- super.onStop();
- //取消此功能的后臺(tái)運(yùn)行以釋放系統(tǒng)內(nèi)存。
- cancelBackgroundRunning();
- }
- /**
- * 在后臺(tái)保留此服務(wù)能力并顯示通知欄。
- */
- private void startForeground() {
- HiLog.info(LABEL_LOG, "startForeground");
- //任務(wù)欄顯示通知
- NotificationRequest request = new NotificationRequest(NOTIFICATION_ID).setTapDismissed(true);
- //
- NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
- content.setTitle("SD card存儲(chǔ)卡已意外移除").setText("請(qǐng)先卸載存儲(chǔ)卡,再將其移除,以防數(shù)據(jù)丟失");
- content.setAdditionalText("21分鐘前");
- //設(shè)置通知欄內(nèi)容
- NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
- request.setContent(notificationContent);
- //在后臺(tái)保留此服務(wù)能力并顯示通知欄。
- keepBackgroundRunning(NOTIFICATION_ID, request);
- }
3.EventHandle事件處理的使用方法
EventHandler 將事件或 Runnable 任務(wù)傳遞到線程的事件隊(duì)列,并在事件或任務(wù)從事件隊(duì)列中出來時(shí)執(zhí)行。
您可以使用 EventHandler 在不同線程之間調(diào)度和處理事件和 Runnable 對(duì)象,并在一定的時(shí)間間隔內(nèi)安排要處理的事件或 Runnable 對(duì)象。您可以使用此類中提供的方法發(fā)送同步或異步事件、延遲事件處理以及設(shè)置事件優(yōu)先級(jí)。
- //定義事件ID
- private static final int EVENT_ABILITY_CONNECT_DONE = 0x1000001;
- private static final int EVENT_ABILITY_DISCONNECT_DONE = 0x1000002;
- private EventHandler eventHandler = new EventHandler(EventRunner.current()) {
- @Override
- protected void processEvent(InnerEvent event) {
- switch (event.eventId) {
- case EVENT_ABILITY_CONNECT_DONE:
- showTips(MainAbilitySlice.this, "Service connect succeeded");
- break;
- case EVENT_ABILITY_DISCONNECT_DONE:
- showTips(MainAbilitySlice.this, "Service disconnect succeeded");
- break;
- default:
- break;
- }
- }
- };
- //發(fā)個(gè)通知,Service 連接成功了
- eventHandler.sendEvent(EVENT_ABILITY_CONNECT_DONE);
效果展示
前臺(tái)ServiceIPC/RPC調(diào)用
文章相關(guān)附件可以點(diǎn)擊下面的原文鏈接前往下載
原文鏈接:https://harmonyos.51cto.com/posts/4776
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)