[文章]HarmonyOS教程一基于分布式调度的能力,实现远程FA的启动

阅读量0
1
0
1. 介绍      
开发者在应用中集成分布式调度能力,通过调用指定能力的分布式接口,实现跨设备能力调度。根据Ability模板及意图的不同,分布式任务调度向开发者提供六种能力:启动远程FA(Feature Ability)、启动远程PA(Particle Ability)、关闭远程PA、连接远程PA、断开连接远程PA和FA跨设备迁移。分布式任务调度的详细介绍可以参考分布式任务调度。

本教程以"基于分布式调度远程启动FA"为例,结合权限申请、Button事件响应、获取设备列表、远程启动FA的开发过程,让您快速了解分布式调度能力。

2. 搭建HarmonyOS环境      
我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。
  • 安装DevEco Studio,详情请参考下载和安装软件。
  • 设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
    • 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
    • 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
  • 开发者可以参考以下链接,完成设备调试的相关配置:
    • 使用真机进行调试
    • 使用模拟器进行调试

3. 申请所需要的权限      
在entrysrcmainconfig.json中申请以下4个权限:
  • ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE:用于允许监听分布式组网内的设备状态变化。
  • ohos.permission.GET_DISTRIBUTED_DEVICE_INFO:用于允许获取分布式组网内的设备列表和设备信息。
  • ohos.permission.GET_BUNDLE_INFO:用于查询其他应用的信息。
  • ohos.permission.DISTRIBUTED_DATASYNC:用于允许不同设备间的数据交换。
    示例代码如下:

  1. module": {
  2. ......
  3.    "reqPermissions": [
  4.     {
  5.        "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
  6.      },
  7.      {
  8.        "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
  9.      },
  10.      {
  11.        "name": "ohos.permission.GET_BUNDLE_INFO"
  12.      },
  13.      {
  14.        "name": "ohos.permission.DISTRIBUTED_DATASYNC"
  15.      }
  16.   ]
  17. }
复制代码

此外,还需要在实现Ability的代码中显式声明需要使用多设备协同访问的权限,示例代码如下:
  1. public class MainAbility extends Ability {
  2. [url=home.php?mod=space&uid=2735960]@Override[/url]
  3. public void onStart(Intent intent) {
  4.     requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"},0);
  5.     super.onStart(intent);  
  6.     super.setMainRoute(MainAbilitySlice.class.getName());
  7.   }
  8. }
复制代码

4. 实现一个Button,响应点击事件
在MainAbilitySlice.java中开发一个页面,并在页面上绘制一个Button,示例代码如下:
  1. @Override
  2. public void onStart(Intent intent) {
  3.     super.onStart(intent);
  4.     DirectionalLayout layout = new DirectionalLayout(this);
  5.     ComponentContainer.LayoutConfig config = new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,  
  6.         ComponentContainer.LayoutConfig.MATCH_PARENT);
  7.     layout.setLayoutConfig(config);
  8.     Button btn = new Button(getContext());
  9.     ShapeElement buttonBg = new ShapeElement();
  10.     buttonBg.setRgbColor(new RgbColor(0, 125, 255));
  11.     buttonBg.setCornerRadius(25);
  12.     btn.setBackground(buttonBg);
  13.     ComponentContainer.LayoutConfig btnConfig = new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,  
  14.         ComponentContainer.LayoutConfig.MATCH_CONTENT);
  15.     btn.setLayoutConfig(btnConfig);
  16.     btn.setTextSize(50);
  17.     btn.setPadding(10, 10, 10, 10);
  18.     btn.setText("Start Remote FA");
  19.     layout.addComponent(btn);
  20.     btn.setClickedListener(component -> {
  21.        // 处理按钮响应,详情请见第3步,获取设备列表。
  22.     });
  23.     super.setUIContent(layout);
  24. }
复制代码

5. 获取设备列表   
在远程启动FA按钮的响应里面实现设备列表的获取,使用DeviceManager.getDeviceList(int flag)获取设备列表,flag通过传入DeviceInfo.FLAG_GET_ONLINE_DEVICE查询所有分布式网络中的在线设备,通过解析返回的DeviceInfo列表对象,获取待被远程启动的FA的设备的deviceId。示例代码如下:
  1. btn.setClickedListener(component -> {
  2. // 处理按钮响应,获取在线设备列表      
  3. List<DeviceInfo> deviceInfoList =  
  4. DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
  5.     for (DeviceInfo deviceInfo : deviceInfoList) {  
  6.         // 远程启动FA,详情请见第4步
  7.     }
  8. });
复制代码

6. 远程启动FA
构建用于远程启动FA的Intent,并远程启动FA。其中的BUNDLE_NAME和ABILITY_NAME为全局变量,表示需要启动的远程FA的BundleName(包名称)和AbilityName(待启动的Ability名称)。示例代码如下:
  1. // 远程启动FA
  2. Intent remoteIntent = new Intent();
  3. // 指定待启动FA的bundleName和abilityName
  4. // 例如:BUNDLE_NAME = "com.huawei.codelab"
  5. //       ABILITY_NAME = "com.huawei.codelab.MainAbility"
  6. // 设置分布式标记,表明当前涉及分布式能力
  7. Operation operation = new Intent.OperationBuilder().withDeviceId(deviceInfo.getDeviceId())
  8.     .withBundleName(BUNDLE_NAME)
  9.     .withAbilityName(ABILITY_NAME)
  10.     .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  11.     .build();
  12. remoteIntent.setOperation(operation);
  13. try {
  14.     // 目标设备是否包含指定FA
  15.     List<AbilityInfo> abilityInfoList = getBundleManager().queryAbilityByIntent(remoteIntent, 0, 0);
  16.     if (abilityInfoList != null && !abilityInfoList.isEmpty()) {
  17.         startAbility(remoteIntent);
  18.     }
  19. } catch (RemoteException e) {
  20.     // 处理异常
  21. }
复制代码


7. 恭喜你     
通过对本教程的学习,你已经学会如何运用分布式调度的能力远程启动FA。

8. 完整示例
以手机为例,点击页面按钮,会拉起同一网络中的其余使用同一华为帐号登录的手机上的指定FA,此处需要至少两台手机进行验证。实现效果如下:

示例代码如下:
在MainAbility.java中完成如下代码:
  1. import ohos.aafwk.ability.Ability;
  2. import ohos.aafwk.content.Intent;

  3. public class MainAbility extends Ability {
  4. @Override
  5. public void onStart(Intent intent) {
  6.     requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"},0);
  7.     super.onStart(intent);
  8.     super.setMainRoute(MainAbilitySlice.class.getName());  
  9.   }
  10. }

  11. 在MainAbilitySlice.java中完成如下代码:


  12. import ohos.aafwk.ability.AbilitySlice;
  13. import ohos.aafwk.content.Intent;
  14. import ohos.aafwk.content.Operation;
  15. import ohos.agp.colors.RgbColor;
  16. import ohos.agp.components.Button;
  17. import ohos.agp.components.ComponentContainer;
  18. import ohos.agp.components.DirectionalLayout;
  19. import ohos.agp.components.element.ShapeElement;
  20. import ohos.bundle.AbilityInfo;
  21. import ohos.distributedschedule.interwork.DeviceInfo;
  22. import ohos.distributedschedule.interwork.DeviceManager;
  23. import ohos.rpc.RemoteException;

  24. import java.util.List;

  25. public class MainAbilitySlice extends AbilitySlice {
  26.     //远程启动FA的BundleName ,请自行填写
  27.     private static final String BUNDLE_NAME = "com.huawei.codelab";
  28.     // 远程启动FA的AbilityName,请自行填写
  29.     private static final String ABILITY_NAME = "com.huawei.codelab.MainAbility";

  30.     @Override
  31.     public void onStart(Intent intent) {
  32.         super.onStart(intent);
  33.         DirectionalLayout layout = new DirectionalLayout(this);
  34.         ComponentContainer.LayoutConfig config = new ComponentContainer.LayoutConfig(
  35.             ComponentContainer.LayoutConfig.MATCH_PARENT,  
  36.             ComponentContainer.LayoutConfig.MATCH_PARENT);
  37.         layout.setLayoutConfig(config);
  38.         Button btn = new Button(getContext());
  39.         ShapeElement buttonBg = new ShapeElement();
  40.         buttonBg.setRgbColor(new RgbColor(0, 125, 255));
  41.         buttonBg.setCornerRadius(25);
  42.         btn.setBackground(buttonBg);
  43.         ComponentContainer.LayoutConfig btnConfig = new ComponentContainer.LayoutConfig(
  44.             ComponentContainer.LayoutConfig.MATCH_PARENT,  
  45.             ComponentContainer.LayoutConfig.MATCH_CONTENT);
  46.         btn.setLayoutConfig(btnConfig);
  47.         btn.setTextSize(50);
  48.         btn.setPadding(10, 10, 10, 10);
  49.         btn.setText("Start Remote FA");
  50.         layout.addComponent(btn);
  51.         btn.setClickedListener(component -> {
  52.             // 处理按钮响应,获取在线设备列
  53.             List<DeviceInfo> deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
  54.             for (DeviceInfo deviceInfo : deviceInfoList) {
  55.                 // 远程启动FA
  56.                 Intent remoteIntent = new Intent();
  57.                 Operation operation = new Intent.OperationBuilder()
  58.                     .withDeviceId(deviceInfo.getDeviceId())
  59.                     .withBundleName(BUNDLE_NAME)
  60.                     .withAbilityName(ABILITY_NAME)
  61.                     .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  62.                     .build();
  63.                 remoteIntent.setOperation(operation);
  64.                 try {
  65.                     List<AbilityInfo> abilityInfoList = getBundleManager().queryAbilityByIntent(remoteIntent, 0, 0);
  66.                     if (abilityInfoList != null && !abilityInfoList.isEmpty()) {
  67.                         startAbility(remoteIntent);
  68.                     }
  69.                 } catch (RemoteException e) {
  70.                     // 处理异常
  71.                 }
  72.             }
  73.         });
  74.         super.setUIContent(layout);
  75.     }
  76. }
复制代码

说明
以上代码仅demo演示参考使用,产品化的代码需要考虑数据校验和国际化。


回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友