赞
踩
目前来看,鸿蒙应用的跨设备分布式调度并不复杂,跟在本应用内调用没有太大却区别,只是多了权限管理和设备管理的相关参数和配置。
这里我将官方文档的代码整理一下,等待以后验证。
首先配置权限,根据已经验证了的DataAbility可知,权限是配置在请求方的Ability的配置文件里的
- {
- "skills": [
- {
- "entities": [
- "entity.system.home"
- ],
- "actions": [
- "action.system.home"
- ]
- }
- ],
- "orientation": "unspecified",
- "name": "com.example.distributeddemo.MainAbility",
- "icon": "$media:icon",
- "description": "$string:mainability_description",
- "label": "DistributedDemo",
- "type": "page",
- "launchType": "standard",
- "reqPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ]
- }

上面reqPermissions就是配置权限,使该Ability支持任务调度,然后就是改造AbilitySlice
首先要实现IAbilityContinuation接口,并实现接口方法,并在onStart里显式申明权限
- public class SampleSlice extends AbilitySlice implements IAbilityContinuation {
- @Override
- public void onStart(Intent intent) {
- // 开发者显示声明需要使用的权限
- requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
- super.onStart(intent);
- }
- }
然后编写UI,添加几个按钮:
- <?xml version="1.0" encoding="utf-8"?>
- <DirectionalLayout
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
- ohos:height="match_parent"
- ohos:width="match_parent"
- ohos:orientation="vertical">
- <Button
- ohos:id="$+id:btn_start_remote_fa"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text="远程启动FA"
- ohos:text_size="19fp"
- ohos:text_color="#FFFFFF"
- ohos:top_padding="8vp"
- ohos:layout_alignment="center"
- ohos:bottom_padding="8vp"
- ohos:right_padding="70vp"
- ohos:left_padding="70vp"
- ohos:top_margin="10vp"
- ohos:background_element="$graphic:background_button"
- ohos:center_in_parent="true"
- ohos:bottom_margin="10vp"/>
- <Button
- ohos:id="$+id:btn_continue_remote_fa"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text="远程迁移FA"
- ohos:text_size="19fp"
- ohos:text_color="#FFFFFF"
- ohos:top_padding="8vp"
- ohos:layout_alignment="center"
- ohos:bottom_padding="8vp"
- ohos:right_padding="70vp"
- ohos:left_padding="70vp"
- ohos:top_margin="10vp"
- ohos:background_element="$graphic:background_button"
- ohos:center_in_parent="true"
- ohos:bottom_margin="10vp"/>
- <Button
- ohos:id="$+id:btn_start_remote_pa"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text="远程启动PA"
- ohos:text_size="19fp"
- ohos:text_color="#FFFFFF"
- ohos:top_padding="8vp"
- ohos:layout_alignment="center"
- ohos:bottom_padding="8vp"
- ohos:right_padding="70vp"
- ohos:left_padding="70vp"
- ohos:top_margin="10vp"
- ohos:background_element="$graphic:background_button"
- ohos:center_in_parent="true"
- ohos:bottom_margin="10vp"/>
- <Button
- ohos:id="$+id:btn_stop_remote_pa"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text="远程关闭PA"
- ohos:text_size="19fp"
- ohos:text_color="#FFFFFF"
- ohos:top_padding="8vp"
- ohos:layout_alignment="center"
- ohos:bottom_padding="8vp"
- ohos:right_padding="70vp"
- ohos:left_padding="70vp"
- ohos:top_margin="10vp"
- ohos:background_element="$graphic:background_button"
- ohos:center_in_parent="true"
- ohos:bottom_margin="10vp"/>
- <Button
- ohos:id="$+id:btn_connect_remote_pa"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text="连接远程PA"
- ohos:text_size="19fp"
- ohos:text_color="#FFFFFF"
- ohos:top_padding="8vp"
- ohos:layout_alignment="center"
- ohos:bottom_padding="8vp"
- ohos:right_padding="70vp"
- ohos:left_padding="70vp"
- ohos:top_margin="10vp"
- ohos:background_element="$graphic:background_button"
- ohos:center_in_parent="true"
- ohos:bottom_margin="10vp"/>
- <Button
- ohos:id="$+id:btn_control_remote_pa"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text="控制连接PA"
- ohos:text_size="19fp"
- ohos:text_color="#FFFFFF"
- ohos:top_padding="8vp"
- ohos:layout_alignment="center"
- ohos:bottom_padding="8vp"
- ohos:right_padding="70vp"
- ohos:left_padding="70vp"
- ohos:top_margin="10vp"
- ohos:background_element="$graphic:background_button"
- ohos:center_in_parent="true"
- ohos:bottom_margin="10vp"/>
- <Button
- ohos:id="$+id:btn_disconnect_remote_pa"
- ohos:width="match_content"
- ohos:height="match_content"
- ohos:text="断开远程PA"
- ohos:text_size="19fp"
- ohos:text_color="#FFFFFF"
- ohos:top_padding="8vp"
- ohos:layout_alignment="center"
- ohos:bottom_padding="8vp"
- ohos:right_padding="70vp"
- ohos:left_padding="70vp"
- ohos:top_margin="10vp"
- ohos:background_element="$graphic:background_button"
- ohos:center_in_parent="true"
- ohos:bottom_margin="10vp"/>
-
- </DirectionalLayout>

初始化按钮,并添加点击事件:
- private MyRemoteProxy mProxy = null;
- private Button btnConnectRemotePA;
- private Button btnControlRemotePA;
- private Button btnContinueRemoteFA;
-
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
- requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
- InsideListener listener = new InsideListener();
- findComponentById(ResourceTable.Id_btn_start_remote_fa).setClickedListener(listener);
- findComponentById(ResourceTable.Id_btn_start_remote_pa).setClickedListener(listener);
- findComponentById(ResourceTable.Id_btn_stop_remote_pa).setClickedListener(listener);
- btnContinueRemoteFA = (Button) findComponentById(ResourceTable.Id_btn_continue_remote_fa);
- btnContinueRemoteFA.setClickedListener(listener);
- btnConnectRemotePA = (Button) findComponentById(ResourceTable.Id_btn_connect_remote_pa);
- btnConnectRemotePA.setClickedListener(listener);
- btnControlRemotePA = (Button) findComponentById(ResourceTable.Id_btn_control_remote_pa);
- btnControlRemotePA.setClickedListener(listener);
- findComponentById(ResourceTable.Id_btn_disconnect_remote_pa).setClickedListener(listener);
- }
-
- class InsideListener implements Component.ClickedListener {
-
- @Override
- public void onClick(Component component) {
- switch (component.getId()) {
- case ResourceTable.Id_btn_start_remote_fa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_start_remote_fa");
-
- break;
- case ResourceTable.Id_btn_continue_remote_fa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_continue_remote_fa");
-
- break;
- case ResourceTable.Id_btn_start_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_start_remote_pa");
-
- break;
- case ResourceTable.Id_btn_stop_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_stop_remote_pa");
- break;
- case ResourceTable.Id_btn_connect_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_connect_remote_pa");
-
- break;
- case ResourceTable.Id_btn_control_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_control_remote_pa");
- break;
- case ResourceTable.Id_btn_disconnect_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_disconnect_remote_pa");
-
- break;
- default:
- break;
- }
- }
- }

通过设备管理DeviceManager提供的getDeviceList接口获取设备列表,并选择一个设备:
- // ISelectResult是一个自定义接口,用来处理指定设备deviceId后执行的行为
- interface ISelectResult {
- void onSelectResult(String deviceId);
- }
-
- // 获得设备列表,开发者可在得到的在线设备列表中选择目标设备执行操作
- private void scheduleRemoteAbility(ISelectResult listener) {
- // 调用DeviceManager的getDeviceList接口,通过FLAG_GET_ONLINE_DEVICE标记获得在线设备列表
- List<DeviceInfo> onlineDevices = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
- // 判断组网设备是否为空
- if (onlineDevices.isEmpty()) {
- listener.onSelectResult(null);
- return;
- }
- int numDevices = onlineDevices.size();
- ArrayList<String> deviceIds = new ArrayList<>(numDevices);
- ArrayList<String> deviceNames = new ArrayList<>(numDevices);
- onlineDevices.forEach((device) -> {
- deviceIds.add(device.getDeviceId());
- deviceNames.add(device.getDeviceName());
- });
- // 以选择首个设备作为目标设备为例
- // 开发者也可按照具体场景,通过别的方式进行设备选择
- String selectDeviceId = deviceIds.get(0);
- listener.onSelectResult(selectDeviceId);
- }

各个按钮对应的点击事件:
- class InsideListener implements Component.ClickedListener {
-
- @Override
- public void onClick(Component component) {
- switch (component.getId()) {
- case ResourceTable.Id_btn_start_remote_fa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_start_remote_fa");
- // 启动远程PA
- scheduleRemoteAbility(new ISelectResult() {
- @Override
- public void onSelectResult(String deviceId) {
- if (deviceId != null) {
- Intent intent = new Intent();
- // 通过scheduleRemoteAbility指定目标设备deviceId
- // 指定待启动FA的bundleName和abilityName
- // 例如:bundleName = "com.huawei.helloworld"
- // abilityName = "com.huawei.helloworld.SampleFeatureAbility"
- // 设置分布式标记,表明当前涉及分布式能力
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId(deviceId)
- .withBundleName("目标bundleName")
- .withAbilityName("目标abilityName")
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- .build();
- intent.setOperation(operation);
- // 通过AbilitySlice包含的startAbility接口实现跨设备启动FA
- startAbility(intent);
- }
- }
- });
- break;
- case ResourceTable.Id_btn_continue_remote_fa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_continue_remote_fa");
- // 用户选择设备后实现业务迁移
- scheduleRemoteAbility(new ISelectResult() {
- @Override
- public void onSelectResult(String deviceId) {
- continueAbility(deviceId);
- }
- });
- break;
- case ResourceTable.Id_btn_start_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_start_remote_pa");
- // 启动远程PA
- scheduleRemoteAbility(new ISelectResult() {
- @Override
- public void onSelectResult(String deviceId) {
- if (deviceId != null) {
- Intent intentToStartPA = new Intent();
- // bundleName和abilityName与待启动PA对应
- // 例如:bundleName = "com.huawei.helloworld"
- // abilityName = "com.huawei.helloworld.SampleParticleAbility"
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId(deviceId)
- .withBundleName("目标bundleName")
- .withAbilityName("目标abilityName")
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- .build();
- intentToStartPA.setOperation(operation);
- startAbility(intentToStartPA);
- }
- }
- });
- break;
- case ResourceTable.Id_btn_stop_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_stop_remote_pa");
- scheduleRemoteAbility(new ISelectResult() {
- @Override
- public void onSelectResult(String deviceId) {
- if (deviceId != null) {
- Intent intentToStopPA = new Intent();
- // bundleName和abilityName与待关闭PA对应
- // 例如:bundleName = "com.huawei.helloworld"
- // abilityName = "com.huawei.helloworld.SampleParticleAbility"
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId(deviceId)
- .withBundleName("目标bundleName")
- .withAbilityName("目标abilityName")
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- .build();
- intentToStopPA.setOperation(operation);
- stopAbility(intentToStopPA);
- }
- }
- });
- break;
- case ResourceTable.Id_btn_connect_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_connect_remote_pa");
- scheduleRemoteAbility(new ISelectResult() {
- @Override
- public void onSelectResult(String deviceId) {
- if (deviceId != null) {
- Intent connectPAIntent = new Intent();
- // bundleName和abilityName与待连接的PA一一对应
- // 例如:bundleName = "com.huawei.helloworld"
- // abilityName = "com.huawei.helloworld.SampleParticleAbility"
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId(deviceId)
- .withBundleName("目标bundleName")
- .withAbilityName("目标abilityName")
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- .build();
- connectPAIntent.setOperation(operation);
- connectAbility(connectPAIntent, conn);
- }
- }
- });
- break;
- case ResourceTable.Id_btn_control_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_control_remote_pa");
- if (mProxy != null) {
- int ret = -1;
- try {
- ret = mProxy.plus(10, 20);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- btnControlRemotePA.setText("控制连接 result = " + ret);
- }
- break;
- case ResourceTable.Id_btn_disconnect_remote_pa:
- HiLog.info(LABEL_LOG, "MainAbilitySlice btn_disconnect_remote_pa");
- btnConnectRemotePA.setText("连接远程PA");
- btnControlRemotePA.setText("控制连接PA");
- disconnectAbility(conn);
- break;
- default:
- break;
- }
- }
- }

最后,FA跨设备迁移的生命周期方法:
流程参见;https://blog.csdn.net/y280903468/article/details/111770977
- @Override
- public boolean onSaveData(IntentParams saveData) {
- String exampleData = String.valueOf(System.currentTimeMillis());
- saveData.setParam("continueParam", exampleData);
- return true;
- }
-
- @Override
- public boolean onRestoreData(IntentParams restoreData) {
- // 远端FA迁移传来的状态数据,开发者可以按照特定的场景对这些数据进行处理
- Object data = restoreData.getParam("continueParam");
- return true;
- }
-
- @Override
- public void onCompleteContinuation(int result) {
- btnContinueRemoteFA.setText("ContinueAbility Done");
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。