HarmonyOS编程跨设备跳转 | Java注释版

想了解更多内容,编版请访问:
和华为官方合作共建的程跨鸿蒙技术社区
https://harmonyos.51cto.com
前言
这里有HarmonyOS文档学习 | 分布式任务调度 | 思维导图,是设备关于文档部分的思维导图,跨设备调用也是跳转用到里面的知识
本文章只是说明书,是注释代码的补充部分。不建议仅根据该文进行实践
正确的编版做法是下载附件中的源码,对照源码和文章的程跨步骤,进行实践复现
跨设备跳转是设备页面跳转的进阶版,如果页面跳转还不熟悉,跳转可以在我的注释第一弹中练习。在安卓中由于没有跨设备的编版接口,所以要实现都需要自己写。程跨而在鸿蒙中,设备只需要用一两行代码就能实现跨设备的跳转的核心操作
三种跨设备跳转的区别
只把页面内容迁移过去
把编辑中的内容迁移过去,b2b供应网支持双向控制
把编辑中的注释内容迁移过去,并可撤回迁移,仅支持单向控制
正文
1. 实现步骤
跨设备调用属于不同页面跳转,所以要有两个以上的Ability
第一步:创建多个Ability,创建后,会在slice、layout和graphic中自动生成对应的文件

第二步:编写xml布局文件,这里只是简单的示例,所以就只有简单的内容

第三步:编写业务逻辑代码
1. 声明权限
因为涉及到跨设备调度,所以为了安全,需要获取权限才能进行交互
声明获取设备列表即设备信息的权限
config.json
"reqPermissions": [ { "name": "ohos.permission.DISTRIBUTED_DATASYNC" }, { "name": "ohos.permission.GET_BUNDLE_INFO" }, { "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE" }, { "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" } ]注意:
第三方应用使用:ohos.permission.DISTRIBUTED_DATASYNC
还需要在主Ability代码中显式声明
public class MainAbility extends Ability { @Override public void onStart(Intent intent) { super.onStart(intent); super.setMainRoute(MainAbilitySlice.class.getName()); // 为第三方应用权限的主动声明 requestPermissionsFromUser(new String[] {"ohos.permission.DISTRIBUTED_DATASYNC"}, 0); } }2. 获取设备Id
只有拿到设备Id,跳转的时候才会根据Id进行页面迁移
3. 实现迁移功能代码
……
补充模拟器如何分布式跨设备测试:
如何多开模拟器,进行分布式应用开发(在DES 2.1版本之前,只能用真机进行分布式跨设备开发)
1. 先确保自己DES版本是2.1以上,可以通过 Help > Check for Updates 进行更新

2. 更新完之后也可以顺便更新自己的 SDK 和 Previewer (Previewer这个挺好用的,写完布局可直接预览而不用开模拟器)

3. 点击 SDK Platforms 和 SDK Tools 查看,在这里我都更新了,反正内存多~

4. 都更新完之后,可以去 File > Settings 或者按 Ctrl + Alt + S 快捷键进入设置面板,点击 DevEco Labs,勾选 Enable Super Device(其他也可以勾选,云南idc服务商Java Previewr贼好用,在写完xml布局文件后,点击最右边导航栏或者按 Alt + 3 就可以预览了)

5. 然后就可以看到模拟器上多了 Super Device

2. 核心代码部分
2.1. 只把页面内容迁移过去
MainAbilitySlice.java
// 通过组件id获得组件 btn1 = (Button)findComponentById(ResourceTable.Id_migration_btn_01); // 设置按钮的点击监听事件 btn1.setClickedListener(component -> { // 要实现跨设备的打开FA // 第一步当然就是要获取到设备id // 通过设备管理的获得设备列表方法获得 List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); // 判空 if (deviceList.isEmpty()) { return null; } // 获得设备数量 int deviceNum = deviceList.size(); // 创建两个列表,分别存设备id和设备名 ArrayList<String> deviceIds = new ArrayList<>(deviceNum); ArrayList<String> deviceNames = new ArrayList<>(deviceNum); // 遍历设备列表,将设备id和设备名分别存到两个列表中 deviceList.forEach(device -> { deviceIds.add(device.getDeviceId()); deviceNames.add(device.getDeviceName()); }); // 我就直接使用deviceIds的第一个元素,作为启动远程设备的目标id String deviceId = deviceIds.get(0); if (deviceId != null) { // 新建Intent,意图:信息的载体 Intent btn_1_intent = new Intent(); // OperationBuilder()方式 Operation operation = new Intent.OperationBuilder() .withDeviceId(deviceId) // 获得设备id,在本地的时候可以为空 .withBundleName("com.anzia.study_2") // 包名,在config.json中可找到 .withAbilityName("com.anzia.study_2.RemoteAbility") // 设立目标页面,一定要路径名!!! .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) // 设立标签,允许跨设备 .build(); // 构建 btn_1_intent.setOperation(operation); // 把operation存进intent中 startAbility(btn_1_intent); } });测试结果:
这里用的是模拟器,项目要在两个模拟上都进行打包安装
安装好后会提示用户获取权限,获得权限才能获取设备Id,从而进行跨设备页面跳转

点击第一个按钮,即可看到另一设备启动

2.2. 把编辑中的内容迁移过去,支持双向控制
由于获取设备Id的这部分代码经常使用,所以可以把这部分封装为一个工具类
如果要获取设备Id,只需要实现这个工具类即可
DeviceUtils.java
public class DeviceUtils { public static String getDeviceId() { // 通过设备管理的亿华云计算获得设备列表方法获得 List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); // 判空 if (deviceList.isEmpty()) { return null; } // 获得设备数量 int deviceNum = deviceList.size(); // 创建两个列表,分别存设备id和设备名 ArrayList<String> deviceIds = new ArrayList<>(deviceNum); ArrayList<String> deviceNames = new ArrayList<>(deviceNum); // 遍历设备列表,将设备id和设备名分别存到两个列表中 deviceList.forEach(device -> { deviceIds.add(device.getDeviceId()); deviceNames.add(device.getDeviceName()); }); // 我就直接使用deviceIds的第一个元素,作为启动远程设备的目标id String deviceIdStr = deviceIds.get(0); return deviceIdStr; } }在MainAbilitySlice.java中实现可交互的页面跳转
使用new ElementName()设备模板页面路径
btn2 = (Button)findComponentById(ResourceTable.Id_migration_btn_02); btn2.setClickedListener(component -> { Intent btn_2_intent = new Intent(); ElementName migrationSliceEn = new ElementName("", "com.anzia.study_2", "MigrationAbility"); btn_2_intent.setElement(migrationSliceEn); startAbility(btn_2_intent); });要把编辑中的文字迁移到其他设备,需要对目标Ability和Slice实现IAbilityContinuation接口,并把构造方法设置为true
MigrationAbility.java

MigrationAbilitySlice.java
public class MigrationAbilitySlice extends AbilitySlice implements IAbilityContinuation { private TextField textField; private Button mgBtn; private String tfStr = ""; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_migration); // 编辑的文字 textField = (TextField) findComponentById(ResourceTable.Id_textfield_migration); // 默认为空 textField.setText(tfStr); mgBtn = (Button) findComponentById(ResourceTable.Id_migration_button); mgBtn.setClickedListener(component -> { // 核心代码,点击按钮,实现FA的迁移 // 第一步获取设备id String deviceId = DeviceUtils.getDeviceId(); if (deviceId != null) { // 实现设备迁移 continueAbility(deviceId); } }); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } @Override public boolean onStartContinuation() { return true; } @Override // 保持数据 public boolean onSaveData(IntentParams intentParams) { // 获得文本框中的文字,并保存到data中,键值对形式 intentParams.setParam("data", textField.getText()); return true; } @Override // 恢复数据 public boolean onRestoreData(IntentParams intentParams) { // 在其他设备恢复数据时,从data读取内容 tfStr = intentParams.getParam("data").toString(); return true; } @Override public void onCompleteContinuation(int i) { } }测试结果
点击按钮进入MigrationAbility页面,在输入框中输入文本内容,再点击按钮,可以看到已经迁移过去了

在目标设备上添加新的内容,再按点击迁移,可以对源设备的内容进行修改。即,可以双向控制

2.3. 把编辑中的内容迁移过去,并可撤回迁移,仅支持单向控制
实现方式和上面的基本差不多,也要实现IAbilityContinuation接口,在部分细节不同
不同点:
1. 在页面中多了一个回迁的按钮
2. 在Slice中
跨设备的方法由continueAbility()变为continueAbilityReversibly()
撤回迁移使用的方法是reverseContinueAbility()
MigrationBackAbilitySlice.java

测试结果:
在文本框输入数据后,点击迁移按钮,就可以在目标设备唤起应用了。点击撤回按钮,也可以把目标设备的页面撤回
这个操作是单向的,不能再迁移后,对目标设备内容修改再点击迁移修改源设备内容。这样做会闪退

3. 总结
因为涉及到设备之间的流转,涉及到安全,所以要在config.json中声明权限。如果想利用第三方设备,除了要在config.json中声明,还需要在代码中显式声明
跨设备需要获取设备Id,如果多个Slice中都要获取设备Id,那么可以将获取设备Id的这个步骤封装为一个工具类
在简单的跨设备调用,可以使用OperationBuilder()方法即可
要将设备编辑中的内容跨设备的话,需要为目标页面的Ability和Slice实现IAbilityContinuation()接口,使用new ElementName()
使用continueAbility进行双向交互
使用continueAbilityReversibly()和reverseContinueAbility()进行单向跨设备跳转及撤回内容
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com

相关文章
用手机和电脑制作棉花娃娃教程(简单易学的棉花娃娃制作指南,从手机到电脑全面解析制作过程)
摘要:在数字时代的今天,人们利用电脑和手机进行各种创作已成为一种普遍现象。而制作棉花娃娃也是一项热门的手工艺品创作。本文将以棉花娃娃制作教程为主题,介绍如何利用电脑和手机进行棉花娃娃的制...2025-11-05海尔和小米净水器,品质对比与选择指南(深入分析两大品牌净水器,帮助你做出明智选择)
摘要:如今,水质污染已成为世界范围内的重要问题,因此净水器的需求日益增加。海尔和小米作为净水器市场的重要参与者,备受消费者关注。本文将深入比较这两个品牌的净水器,从品质、功能、价格等多个...2025-11-05250g固态硬盘的优势和应用领域(性能稳定可靠,适用于个人和企业用户)
摘要:随着科技的不断进步和存储需求的增加,固态硬盘逐渐成为了许多人的首选。而其中,250g固态硬盘以其出色的性能和合理的容量,成为了许多个人和企业用户的理想之选。本文将深入探讨250g固...2025-11-05- 摘要:随着科技的不断发展,人们对于电脑周边设备的需求也越来越高。在众多品牌的鼠标中,微软灵巧600以其出色的性能和便捷的操作成为了众多用户的首选。本文将详细介绍微软灵巧600的优点和特点...2025-11-05
掌握uptool教程,轻松应对工具操作(提升效率的关键工具,uptool简易教程)
摘要:在数字化时代,我们离不开各种工具来提高工作效率和解决问题。其中,uptool是一款功能强大且易于使用的工具,能够帮助我们快速处理各种任务。本文将为您介绍uptool的基本操作和使用...2025-11-05三星EVO960的性能表现如何?(一款高性能固态硬盘的评测与分析)
摘要:在现代计算机中,固态硬盘已经成为了提升系统性能的重要组成部分。三星EVO960作为一款高性能的固态硬盘,备受关注。本文将对其性能进行全面评测,以帮助读者更好地了解和选择。文...2025-11-05

最新评论