前言
- 对于分布式能力的接口,HarmonyOS 在 API Version 4 提供了一波,然后到 API Version 7 又提供了另一波,因此 API Version 4 的接口就不再被维护了,后续应该使用最新的 API Version 7 的接口。
- 但是,官方的开发工具里面提供的 Super Device,即支持调试分布式功能的远程双设备,都还处在 API Version 6 阶段,如下:  
- 也就是说,目前要用 API Versoin 7 的接口去实现分布式功能,只能在真机上开发调试,从下图来看,至少需要两台 P40 Pro:  
- 且,API Version 7 目前还处在 Beta 版本,使用起来可能会遇到各种问题,将来也可能会有变动,如下:  
- 因此,在经济条件有限的情况下,我们目前主要还是使用 API Version 4 的接口来开发分布式功能,等官方普遍支持 API Version 7 了,再使用该新版本接口。
权限申请
- 在使用分布式能力之前,需要先申请对应权限的使用,比如:GET_DISTRIBUTED_DEVICE_INFO,用来获取分布式的设备信息;DISTRIBUTED_DATASYNC,用来在分布式设备之间进行数据同步
- 上述两个权限都需要在config.json中进行配置申明,如下: 
- 权限分为两种类别:敏感权限与非敏感权限,前者的授予模式(grantMode)为用户授予(user_grant),也就是需要在运行时弹窗向用户申请权限的使用;后者的授予模式为系统授予(system_grant),是在安装时向用户列出需要的权限,当用户同意安装时,这些权限就被授权给了应用。
- 上面我们的分布式权限中:GET_DISTRIBUTED_DEVICE_INFO是非敏感权限,在config.json中声明即可;DISTRIBUTED_DATASYNC是敏感权限,还需要调用接口向用户申请,如下是在 MainAbility 中的 onStart 回调中,即应用一打开就申请使用: 
- 效果如图: 
分布式拉起
- 分布式拉起,即运行组网中分布式设备中的应用,这种拉起既可以拉起本设备的本应用、本设备的其他应用,也可以拉起组网中其他设备的本应用、其他设备的其他应用
- 首先,调用getDeviceList获取组网中的分布式设备信息,并取出networkId如下
const result = await FeatureAbility.getDeviceList();
const networkId = result.data[0].networkId- 然后构建target 表示要拉起的目标,如下:
const target = {
    // bundleName、abilityName 用来确定要拉起哪个应用的哪个ability
    bundleName: "com.tanleidd.email",
    abilityName: "com.tanleidd.email.MainAbility",
    // 如果 networkId 为空,则表示拉起的是本设备上的应用
    // 如果要拉起的是分布式设备上的应用,需要确保目的设备上已安装了目的应用
    networkId,  
};- target 中还可以包含url、data,表示要迁移到的 page、以及传递的数据,如下:
const target = {
    bundleName: "com.tanleidd.email",
    abilityName: "com.tanleidd.email.MainAbility",
    networkId,
    url: "pages/write_email/write_email",
    // 这里的 data 会覆盖目的页面的 data 数据,可以直接通过 this.xx 访问
    data: {
        to,
        subject,
        text,
    }
};- 最后通过startAbility开始拉起 Ability
await FeatureAbility.startAbility(target);- 完整代码如下: 
- 分布式拉起效果如下: 
- 然后我们验证一下,拉起其他设备的其他应用,如下: 
- 分布式拉起效果如下: 
分布式迁移
- 分布式迁移,即将本应用的当前 Ability 迁移到组网中的其他分布式设备中继续运行。
- 分布式迁移使用的是 - continueAbility接口,如下: 
- 当开始迁移时,以下四个回调方法将被依次调用:在源设备上调用 onStartContinuation、onSaveData,在目的设备上调用onRestoreData,最后在源设备上调用onCompleteContinuation,如下:
onStartContinuation() {
    return true;    // 返回 true 表示允许迁移
},
onSaveData(savedData) {
    const { to, subject, text } = this;
    const data = {
        to,
        subject,
        text
    }
    // savedData 是出参,在源设备上将要迁移的数据保存在 savedData 中
    Object.assign(savedData, data);
},
onRestoreData(restoreData) {
    // restoreData,是 savedData 的副本,用于在目的设备中恢复数据
    const { to, subject, text } = restoreData;
    this.to = to;
    this.subject = subject;
    this.text = text;
},
onCompleteContinuation(code) {
    // code 是迁移完成的结果。0:成功。 -1:失败
    console.log(code)
},- 分布式迁移效果如下: 
总结
- 分布式拉起、迁移,都可以达到将应用流转到其他设备上继续运行的目的,在拉起中,通过 target 对象中的 data 来传递数据;在迁移中,通过 savedData、restoreData来传递数据。
- 在分布式拉起中,除了可以拉起当前应用外,还可以拉起目的设备中其他已安装的应用;而在分布式迁移中,只能迁移当前应用。
- 在分布式迁移中,不需要调用getDeviceList获取分布式设备信息,以及networkId,因此不需要申明使用GET_DISTRIBUTED_DEVICE_INFO权限。
最后
因为JAVA相关能力支持更早更完善,相关教学视频都是围绕JAVA开发来展开的,社区中基于JAVA来开发HarmonyOS应用的开发者要多于基于JS的开发者,因此在网上搜索相关问题时往往都是关于JAVA的回答,对基于JS的开发者来说,遇到问题常常找不到解决的办法,期望大家在解决某些自己遇到的问题时,能够在社区或博客里多分享分享 ^_^ ~。










