zl程序教程

您现在的位置是:首页 >  其他

当前栏目

HarmonyOS Sample 之 ServiceAbility 跨设备接口调用

2023-03-15 22:45:55 时间

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

ServiceAbility 跨设备接口调用

介绍

本示例演示了Service Ability的启动、停止、连接、断开连接等操作,支持对跨设备的Service Ability进行操作。

你将学会以下三个知识点:

1.IDL的使用,以及IPC方法的调用

2.前台Service的使用方法

3.EventHandle事件处理的使用方法

搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载。

设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

  • 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
  • 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。

代码结构解读

后台逻辑

  1. │  config.json #全局配置文件 
  2. │ 
  3. ├─idl 
  4. │  └─ohos 
  5. │      └─samples 
  6. │          └─serviceability 
  7. │                  IRemoteAgent.idl #提供远程接口idl文件 
  8. │ 
  9. ├─java 
  10. │  └─ohos 
  11. │      └─samples 
  12. │          └─serviceability 
  13. │              │  ForegroundServiceAbility.java #前台Service Ability 
  14. │              │  LocalServiceAbility.java #模拟本地的Service Ability 
  15. │              │  MainAbility.java   
  16. │              │  RemoteAbility.java    #模拟远端的Service Ability 
  17. │              │ 
  18. │              └─slice 
  19. │                      MainAbilitySlice.java #主能力页 

 页面布局文件只有一个 main_slice.xml

页面布局

三个知识点

1.IDL的使用,以及IPC方法的调用

术语:

当客户端和服务器通信时,需要定义双方都认可的接口,以保障双方可以成功通信,HarmonyOS IDL(HarmonyOS Interface Definition Language)则是一种定义此类接口的工具。

跨进程调用(IPC)inter-process communication 或 跨设备调用(RPC)remote procedure call

IDL接口使用规范:

https://developer.harmonyos.com/cn/docs/documentation/doc-references/idl-overview-0000001050762835

先声明权限,同时敏感权限还需要请求用户授权,前几篇都有写过这里就不写了。

  1. "reqPermissions": [ 
  2.     { 
  3.       "name""ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" 
  4.     }, 
  5.     ... 
  6.     { 
  7.       "name""ohos.permission.DISTRIBUTED_DATASYNC" 
  8.     } 
  9.   ] 

 a.创建.idl文件

HarmonyOS Sample 之 ServiceAbility 跨设备接口调用-鸿蒙HarmonyOS技术社区

IRemoteAgent.idl

  1. // Declare any non-default types here with sequenceable or interface statements 
  2.  
  3. interface ohos.samples.serviceability.IRemoteAgent { 
  4.     /* 
  5.      * Demo service method use some parameters 
  6.      */ 
  7.     void setRemoteObject([in] String param); 

 b.编译idl文件,生成对应的接口类、桩类和代理类

HarmonyOS Sample 之 ServiceAbility 跨设备接口调用-鸿蒙HarmonyOS技术社区
HarmonyOS Sample 之 ServiceAbility 跨设备接口调用-鸿蒙HarmonyOS技术社区

c.服务端IDL的实现

  1. private static final String DESCRIPTOR = "ohos.samples.serviceability.RemoteAbility"
  2.  
  3. //idl的服务端实现, 
  4. RemoteAgentStub remoteAgentStub = new RemoteAgentStub(DESCRIPTOR) { 
  5.     @Override 
  6.     public void setRemoteObject(String param) { 
  7.         HiLog.info(LABEL_LOG, "%{public}s""setRemoteObject:"+param); 
  8.         //不能这样,要用下面通知的方式 
  9.         //showTips(RemoteAbility.this, param); 
  10.         //赋值 
  11.         param_mess=param; 
  12.         //事件通知 
  13.         eventHandler.sendEvent(EVENT_ABILITY_MESS); 
  14.  
  15.     } 
  16.  
  17. }; 

 d.客户端调用IPC方法 

  1. //IDL代理类 
  2. private  RemoteAgentProxy remoteAgentProxy; 
  3.  
  4. /** 
  5.  * 连接 Service 
  6.  * @param isConnectRemote 
  7.  */ 
  8. private void connectService(boolean isConnectRemote) { 
  9.     //三元表达式,判断连接本地还是远端Service 
  10.     Intent intent = isConnectRemote 
  11.             ? getRemoteServiceIntent(REMOTE_BUNDLE, REMOTE_SERVICE) 
  12.             : getLocalServiceIntent(LOCAL_BUNDLE, NORMAL_SERVICE); 
  13.  
  14.  
  15.     //连接 Service 
  16.     boolean isConnect=connectAbility(intent,connection); 
  17.     if (isConnect && remoteAgentProxy!=null) { 
  18.         try { 
  19.             //调用服务端IPC方法 
  20.             remoteAgentProxy.setRemoteObject("This param from client"); 
  21.         } catch (RemoteException e) { 
  22.             HiLog.error(LABEL_LOG, "%{public}s""onAbilityConnectDone RemoteException"); 
  23.         } 
  24.     } 
  25.  
  26.  
  27. //建立连接,实例化代理对象 
  28. private IAbilityConnection connection = new IAbilityConnection() { 
  29.     @Override 
  30.     public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) { 
  31.         //发个通知,Service 连接成功了 
  32.         eventHandler.sendEvent(EVENT_ABILITY_CONNECT_DONE); 
  33.         //实例化代理对象 
  34.         remoteAgentProxy = new RemoteAgentProxy(iRemoteObject); 
  35.     } 
  36.  
  37.     @Override 
  38.     public void onAbilityDisconnectDone(ElementName elementName, int resultCode) { 
  39.         //发个通知,Service 断开连接了,主动断开不会执行,关闭服务端会执行 
  40.         eventHandler.sendEvent(EVENT_ABILITY_DISCONNECT_DONE); 
  41.     } 
  42. }; 

 2.前台Service的使用方法

a.权限声明:

  1. "reqPermissions": [ 
  2.       { 
  3.         "name""ohos.permission.KEEP_BACKGROUND_RUNNING" 
  4.       }, 
  5.       ... 
  6.     ] 

b.设置通知栏内容,然后,

  • 在onStart方法调用keepBackgroundRunning方法在后台保留此服务能力并显示通知栏。
  • 在onStop方法调用cancelBackgroundRunning()方法取消此功能的后台运行以释放系统内存。
  1. //通知ID 
  2. private static final int NOTIFICATION_ID = 0XD0000002; 
  3.  
  4. @Override 
  5. protected void onStart(Intent intent) { 
  6.     //调用方法 
  7.     startForeground(); 
  8.     super.onStart(intent); 
  9.  
  10. @Override 
  11. protected void onStop() { 
  12.     super.onStop(); 
  13.     //取消此功能的后台运行以释放系统内存。 
  14.     cancelBackgroundRunning(); 
  15.  
  16.  
  17. /** 
  18.  * 在后台保留此服务能力并显示通知栏。 
  19.  */ 
  20. private void startForeground() { 
  21.     HiLog.info(LABEL_LOG, "startForeground"); 
  22.  
  23.     //任务栏显示通知 
  24.     NotificationRequest request = new NotificationRequest(NOTIFICATION_ID).setTapDismissed(true); 
  25.     // 
  26.     NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent(); 
  27.  
  28.     content.setTitle("SD card存储卡已意外移除").setText("请先卸载存储卡,再将其移除,以防数据丢失"); 
  29.     content.setAdditionalText("21分钟前"); 
  30.     //设置通知栏内容 
  31.     NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content); 
  32.     request.setContent(notificationContent); 
  33.  
  34.     //在后台保留此服务能力并显示通知栏。 
  35.     keepBackgroundRunning(NOTIFICATION_ID, request); 
  36.  

3.EventHandle事件处理的使用方法

EventHandler 将事件或 Runnable 任务传递到线程的事件队列,并在事件或任务从事件队列中出来时执行。

您可以使用 EventHandler 在不同线程之间调度和处理事件和 Runnable 对象,并在一定的时间间隔内安排要处理的事件或 Runnable 对象。您可以使用此类中提供的方法发送同步或异步事件、延迟事件处理以及设置事件优先级。

  1. //定义事件ID 
  2. private static final int EVENT_ABILITY_CONNECT_DONE = 0x1000001; 
  3. private static final int EVENT_ABILITY_DISCONNECT_DONE = 0x1000002; 
  4.  
  5.  
  6. private EventHandler eventHandler = new EventHandler(EventRunner.current()) { 
  7.         @Override 
  8.         protected void processEvent(InnerEvent event) { 
  9.             switch (event.eventId) { 
  10.                 case EVENT_ABILITY_CONNECT_DONE: 
  11.                     showTips(MainAbilitySlice.this, "Service connect succeeded"); 
  12.                     break; 
  13.                 case EVENT_ABILITY_DISCONNECT_DONE: 
  14.                     showTips(MainAbilitySlice.this, "Service disconnect succeeded"); 
  15.                     break; 
  16.                 default
  17.                     break; 
  18.             } 
  19.         } 
  20.     }; 
  21.  
  22.  
  23. //发个通知,Service 连接成功了 
  24. eventHandler.sendEvent(EVENT_ABILITY_CONNECT_DONE); 

效果展示

前台ServiceIPC/RPC调用

文章相关附件可以点击下面的原文链接前往下载

原文链接:https://harmonyos.51cto.com/posts/4776

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com