0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙应用开发入门之跨设备迁移

鸿蒙系统HarmonyOS 来源:51cto 作者:zhonghongfa 2021-04-16 15:38 次阅读

1. 分布式任务调度概述

HarmonyOS中,分布式任务调度平台对搭载HarmonyOS的多设备构筑的“超级虚拟终端”提供统一的组件管理能力,为应用定义统一的能力基线、接口形式、数据结构、服务描述语言,屏蔽硬件差异;支持远程启动、远程调用、业务无缝迁移等分布式任务。

2. 实现调度的约束与限制

1)远程调用PA/FA,开发者需要在Intent中设置支持分布式的标记(例如:Intent.FLAG_ABILITYSLICE_MULTI_DEVICE表示该应用支持分布式调度),否则将无法获得分布式能力。

2)开发者通过在config.json中的reqPermissions字段里添加权限申请:

(1)以获取跨设备连接的能力和分布式数据传输的权限。

分布式数据传输的权限:

{“name”: “ohos.permission.servicebus.ACCESS_SERVICE”}

三方应用使用权限:

{“name”: “ohos.permission.servicebus.DISTRIBUTED_DATASYNC”}

系统应用使用权限:

{“name”: “com.huawei.hwddmp.servicebus.BIND_SERVICE”}

(2)另外还有三个获取分布式设备信息需要的权限:

{“name”: “ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE”},

{“name”: “ohos.permission.GET_DISTRIBUTED_DEVICE_INFO” },

{ “name”: “ohos.permission.GET_BUNDLE_INFO”}

注意:还需要在开发的时候,要在Ability里主动声明,要用到的权限。

3)FA(Feature Ability,Page模板的Ability)的调用支持启动和迁移行为,在进行调度时:

(1)当启动FA时,需要开发者在Intent中指定对端设备的deviceId、bundleName和abilityName。

(2)FA的迁移实现相同bundleName和abilityName的FA跨设备迁移,因此需要指定迁移设备的deviceId。

3. 实现场景介绍

下面以设备A(本地设备)和设备B(远端设备)为例,介绍下面我们要实现的场景:

1)设备A启动设备B的FA:在设备A上通过本地应用提供的启动按钮,启动设备B上对应的FA。

2)设备A的FA迁移至设备B:设备A上通过本地应用提供的迁移按钮,将设备A的业务无缝迁移到设备B中。

3)设备A的FA迁移至设备B,还可以实现主动撤回迁移。

4. 具体实现前先了解要用的接口

1)启动远程FA

startAbility(Intent intent)接口提供启动指定设备上FA和PA的能力,Intent中指定待启动FA的设备deviceId、bundleName和abilityName。

2)迁移FA

continueAbility(String deviceId)接口提供将本地FA迁移到指定设备上的能力,continueAbilityReversibly(String deviceId) 接口提供将本地FA迁移到指定设备上的能力,这种迁移可撤回, reverseContinueAbility()接口提供撤回迁移的能力。

5. 实战远程启动FA页面

1)编程实现上面场景的界面:

ability_main.xml

《?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:migration_btn_01”

ohos:height=“match_content”

ohos:width=“300vp”

ohos:text=“1.启动远程设备的FA”

ohos:text_size=“20fp”

ohos:text_color=“#ffffff”

ohos:background_element=“$graphic:button_bg”

ohos:layout_alignment=“horizontal_center”

ohos:top_padding=“8vp”

ohos:bottom_padding=“8vp”

ohos:left_padding=“40vp”

ohos:right_padding=“40vp”

ohos:top_margin=“20vp”

/》

《Button

ohos:id=“$+id:migration_btn_02”

ohos:height=“match_content”

ohos:width=“300vp”

ohos:text=“2.迁移到远程设备”

ohos:text_size=“20fp”

ohos:text_color=“#ffffff”

ohos:background_element=“$graphic:button_bg”

ohos:layout_alignment=“horizontal_center”

ohos:top_padding=“8vp”

ohos:bottom_padding=“8vp”

ohos:left_padding=“40vp”

ohos:right_padding=“40vp”

ohos:top_margin=“20vp”

/》

《Button

ohos:id=“$+id:migration_btn_03”

ohos:height=“match_content”

ohos:width=“300vp”

ohos:text=“3.可迁回的迁移远程设备”

ohos:text_size=“20fp”

ohos:text_color=“#ffffff”

ohos:background_element=“$graphic:button_bg”

ohos:layout_alignment=“horizontal_center”

ohos:top_padding=“8vp”

ohos:bottom_padding=“8vp”

ohos:left_padding=“40vp”

ohos:right_padding=“40vp”

ohos:top_margin=“20vp”

/》

《/DirectionalLayout》1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.

复制button_bg.xml

《?xml version=“1.0” encoding=“utf-8”?》

《shape xmlns:ohos=“http://schemas.huawei.com/res/ohos”

ohos:shape=“rectangle”》

《solid ohos:color=“#007DFF”/》

《corners ohos:radius=“40”/》

《/shape》1.2.3.4.5.6.

复制MigrationAbility和MigrationBackAbility

// 调用AbilitySlice模板实现一个用于控制基础功能的FA

// Ability和AbilitySlice类均需要实现IAbilityContinuation及其方法,才可以实现FA迁移。AbilitySlice的代码示例如下

public class SampleSlice extends AbilitySlice implements IAbilityContinuation {

@Override

public void onStart(Intent intent) {

super.onStart(intent);

super.setUIContent(layout);

}1.2.3.4.5.6.7.8.9.

复制ability_migration.xml

《?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:background_element=“#00ffff”

ohos:orientation=“vertical”》

《Text

ohos:id=“$+id:text_title”

ohos:height=“match_content”

ohos:width=“250vp”

ohos:background_element=“#0088bb”

ohos:layout_alignment=“horizontal_center”

ohos:text=“下面是一个可编辑的文本框”

ohos:text_size=“50”

ohos:padding=“5vp”

ohos:top_margin=“30vp”

/》

《TextField

ohos:id=“$+id:textfield_back”

ohos:height=“250vp”

ohos:width=“250vp”

ohos:hint=“请输入。。.”

ohos:layout_alignment=“horizontal_center”

ohos:background_element=“#ffffff”

ohos:text_color=“#888888”

ohos:text_size=“20fp”

ohos:padding=“5vp”

/》

《Button

ohos:id=“$+id:migration_button”

ohos:height=“match_content”

ohos:width=“match_content”

ohos:text=“点击迁移”

ohos:text_size=“20fp”

ohos:text_color=“#ffffff”

ohos:background_element=“$graphic:button_bg”

ohos:top_padding=“8vp”

ohos:bottom_padding=“8vp”

ohos:left_padding=“50vp”

ohos:right_padding=“50vp”

ohos:layout_alignment=“horizontal_center”

ohos:top_margin=“30vp”

/》

《/DirectionalLayout》1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.

复制ability_migration_back.xml比ability_migration.xml多一个迁回按钮,另外主页上点击按钮跳转等,略。。.

2)使用分布式能力要求开发者在Ability对应的config.json中声明多设备协同访问的权限:

(1)三方应用部署权限、分布式数据传输的权限、系统应用使用权限的申请。

{

“reqPermissions”: [

{“name”: “ohos.permission.DISTRIBUTED_DATASYNC”},

{“name”: “ohos.permission.servicebus.ACCESS_SERVICE”},

{“name”: “com.huawei.hwddmp.servicebus.BIND_SERVICE”}

}1.2.3.4.5.6.7.

复制(2)声明分布式获取设备列表及设备信息的权限,如下所示:

{

“reqPermissions”: [

{“name”: “ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE”},

{“name”: “ohos.permission.GET_DISTRIBUTED_DEVICE_INFO” },

{“name”: “ohos.permission.GET_BUNDLE_INFO”}

}1.2.3.4.5.6.7.

复制(3)对于三方应用还要求在实现Ability的代码中显式声明需要使用的权限。

public class SampleSlice extends AbilitySlice implements IAbilityContinuation {

@Override

public void onStart(Intent intent) {

// 开发者显示声明需要使用的权限

requestPermissionsFromUser(new String[]{“ohos.permission.DISTRIBUTED_DATASYNC”,

“ohos.permission.servicebus.ACCESS_SERVICE”,

“com.huawei.hwddmp.servicebus.BIND_SERVICE”}, 0);

super.onStart(intent);

}

}1.2.3.4.5.6.7.8.9.10.

复制3) 为启动远程FA的按钮添加点击事件,获取设备信息,实现启动远程FA的能力。

Button btn1 = (Button) findComponentById(ResourceTable.Id_migration_btn_01);

btn1.setClickedListener(new Component.ClickedListener() {

@Override

public void onClick(Component component) {

// 调用DeviceManager的getDeviceList接口,通过FLAG_GET_ONLINE_DEVICE标记获得在线设备列表

List《DeviceInfo》 onlineDevices = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);

// 判断组网设备是否为空

if (onlineDevices.isEmpty()) {

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);

//获取设备ID,最好放到工具类里,很多地方要用!

if(selectDeviceId!=null){

Intent intent2 = new Intent();

Operation operation = new Intent.OperationBuilder()

.withDeviceId(selectDeviceId)

.withBundleName(“cn.ybzy.hmsdemo”)

.withAbilityName(“cn.ybzy.hmsdemo.RemoteAbility”)

.withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)

.build();

intent2.setOperation(operation);

// 通过AbilitySlice包含的startAbility接口实现跨设备启动FA

startAbility(intent2);

}

}

});1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.

复制6. 实战将设备A运行时的FA迁移到设备B,实现业务在设备间无缝迁移。

MigrationAbility

public class MigrationAbility extends Ability implements IAbilityContinuation {

@Override

public void onStart(Intent intent) {

super.onStart(intent);

super.setMainRoute(MigrationAbilitySlice.class.getName());

}

@Override

public boolean onStartContinuation() {

return true;

}

@Override

public boolean onSaveData(IntentParams intentParams) {

return true;

}

@Override

public boolean onRestoreData(IntentParams intentParams) {

return true;

}

@Override

public void onCompleteContinuation(int i) {

}

}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.

复制

MigrationAbilitySlice

public class MigrationAbilitySlice extends AbilitySlice implements IAbilityContinuation {

TextField textField;

String textStr = “请输入数据。。.”;

@Override

public void onStart(Intent intent) {

super.onStart(intent);

super.setUIContent(ResourceTable.Layout_ability_migration);

textField = (TextField)findComponentById(ResourceTable.Id_textfield_migration);

textField.setText(textStr);

Button btn = (Button) findComponentById(ResourceTable.Id_migration_button);

btn.setClickedListener(new Component.ClickedListener() {

@Override

public void onClick(Component component) {

String deviceId = getDeviceId();

if(deviceId!=null){

continueAbility(deviceId);

}

}

});

}

private String getDeviceId(){

// 调用DeviceManager的getDeviceList接口,通过FLAG_GET_ONLINE_DEVICE标记获得在线设备列表

List《DeviceInfo》 onlineDevices = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);

// 判断组网设备是否为空

if (onlineDevices.isEmpty()) {

return null;

}

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);

return selectDeviceId;

}

@Override

public boolean onStartContinuation() {

return true;

}

@Override

public boolean onSaveData(IntentParams intentParams) {

intentParams.setParam(“data”,textField.getText());

return true;

}

@Override

public boolean onRestoreData(IntentParams intentParams) {

textStr = intentParams.getParam(“data”).toString();

return true;

}

@Override

public void onCompleteContinuation(int i) {

}

@Override

public void onRemoteTerminated() {

}

}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.

复制此外,不同于启动行为,FA的迁移还涉及到状态数据的传递。为此,继承的IAbilityContinuation接口为开发者提供迁移过程中特定事件的管理能力。通过自定义迁移事件相关的行为,最终实现对Ability的迁移。主要以较为常用的两个事件,包括迁移发起端完成迁移的回调onCompleteContinuation(int result)以及接收到远端迁移行为传递数据的回调onRestoreData(IntentParams restoreData)。其他还包括迁移到远端设备的FA关闭的回调onRemoteTerminated()、用于本地迁移发起时保存状态数据的回调onSaveData(IntentParams saveData)和本地发起迁移的回调onStartContinuation()。

7. 请求回迁

Button btn1 = (Button) findComponentById(ResourceTable.Id_migration_button_back);

btn1.setClickedListener(new Component.ClickedListener() {

@Override

public void onClick(Component component) {

String deviceId = DeviceUtils.getDeviceId();

if(deviceId!=null){

continueAbilityReversibly(deviceId); //可撤回迁移

}

}

});

Button btn2 = (Button) findComponentById(ResourceTable.Id_migration_button_back2);

btn2.setClickedListener(new Component.ClickedListener() {

@Override

public void onClick(Component component) {

reverseContinueAbility(); //撤回迁移

}

});1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.

复制1)设备A上的Page请求回迁。

2)系统回调设备B上Page及其AbilitySlice栈中所有AbilitySlice实例的IAbilityContinuation.onStartContinuation()方法,以确认当前是否可以立即迁移。

3)如果可以立即迁移,则系统回调设备B上Page及其AbilitySlice栈中所有AbilitySlice实例的IAbilityContinuation.onSaveData()方法,以便保存回迁后恢复状态必须的数据。

4)如果保存数据成功,则系统在设备A上Page恢复AbilitySlice栈,然后回调IAbilityContinuation.onRestoreData()方法,传递此前保存的数据。

5)如果数据恢复成功,则系统终止设备B上Page的生命周期。

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • HarmonyOS
    +关注

    关注

    79

    文章

    1840

    浏览量

    29266
收藏 人收藏

    评论

    相关推荐

    鸿蒙OS 跨设备迁移

    设备迁移(下文简称“迁移”)支持将 Page 在同一用户的不同设备迁移,以便支持用户无缝切换的诉求。以 Page 从
    的头像 发表于 01-31 15:47 856次阅读

    如何理解鸿蒙OS是设备的?

    谁能帮忙解释鸿蒙OS是怎样实现平台的?
    发表于 09-08 18:17

    怎么入门DevEco Studio 分布式设备应用开发

    想知道怎么入门DevEco Studio 分布式设备应用开发
    发表于 09-18 15:50

    鸿蒙设备学习菜鸟指南》 【索引及PDF和工具分享】

    本帖最后由 HonestQiao 于 2020-11-3 14:29 编辑 《鸿蒙设备学习菜鸟指南》 【目录索引】本帖为索引贴,各节的内容,将逐步发布。本菜鸟指南的写作目的,是为了让新上手
    发表于 10-30 13:14

    鸿蒙设备学习菜鸟指南》 【五、搭建开发环境】

    ` 本帖最后由 HonestQiao 于 2020-10-30 14:00 编辑 《鸿蒙设备学习菜鸟指南》 【五、搭建开发环境】[目录索引]五、搭建
    发表于 10-30 13:59

    鸿蒙设备学习菜鸟指南》【七、开发

    鸿蒙设备学习菜鸟指南》【七、开发】[目录索引]七、开发开发部分,我们在这里面,就不详细讲了,
    发表于 11-01 11:41

    课程推荐【1】 | 鸿蒙设备开发入门

    ,Android。出版书籍《物联网——嵌入式开发实战》你将会学到:本课程将带大家入门HarmonyOS设备开发,以Hi3861鸿蒙
    发表于 12-28 16:26

    #2020征文-手机#【鸿蒙基地】鸿蒙设备启动窗口:Page Ability

    HarmonyOS的核心特性(或称为卖点)之一就是软总线技术,而Page Ability的设备迁移是软总线的一个具体技术实现。所谓设备
    发表于 12-31 11:56

    #2020征文-手机#【鸿蒙基地】鸿蒙设备启动窗口:Page Ability

    HarmonyOS的核心特性(或称为卖点)之一就是软总线技术,而Page Ability的设备迁移是软总线的一个具体技术实现。所谓设备
    发表于 01-25 14:13

    HarmonyOS分布式——设备迁移

    HarmonyOS分布式——设备迁移
    发表于 06-26 14:34

    HarmonyOS教程—基于设备迁移和分布式文件能力,实现邮件的设备编辑和附件的调用

    操作。想要解决这些问题,我们可以通过HarmonyOS的分布式能力实现任务的设备迁移,保证业务在手机、平板等终端间无缝衔接,轻松的完成多设备之间的协同办公。本篇Codelab文档,我
    发表于 09-09 10:03

    鸿蒙应用开发入门资料合集

    应用开发入门资料六:实现设备迁移分布式任务调度概述在HarmonyOS中,分布式任务调度平台对搭载HarmonyOS的多
    发表于 03-22 11:23

    通过HarmonyOS分布式能力实现任务的设备迁移设计资料分享

    的文档或图片素材,此时需要在不同设备间反复操作。想要解决这些问题,我们可以通过 HarmonyOS 的分布式能力实现任务的设备迁移,保证业务在手机、平板等终端间无缝衔接,轻松的完成多
    发表于 03-25 16:59

    请问DevEco Studio支持打开两个远程模拟器,演示设备迁移吗?

    DevEco Studio支持打开两个远程模拟器,演示设备迁移吗?
    发表于 06-07 10:02

    HarmonyOS应用开发-DiseributedVideoCodelab设备视频迁移

    说明:此Demo用于设备迁移视频内容。您可以方便地跨设备迁移视频内容,然后在源设备远程控制、操
    发表于 07-05 10:24